Update for v1.0alpha2

This commit is contained in:
James Deng 2024-03-01 19:54:35 +08:00
parent 21ba93e8b5
commit 3ba6ecc050
235 changed files with 33436 additions and 434 deletions

View file

@ -29,6 +29,9 @@ config BR2_TARGET_OPENSBI_CUSTOM_VERSION
config BR2_TARGET_OPENSBI_CUSTOM_TARBALL
bool "Custom tarball"
config BR2_TARGET_OPENSBI_CUSTOM_LOCAL
bool "Custom local dir"
config BR2_TARGET_OPENSBI_CUSTOM_GIT
bool "Custom Git repository"
@ -42,6 +45,14 @@ config BR2_TARGET_OPENSBI_CUSTOM_TARBALL_LOCATION
string "URL of custom OpenSBI tarball"
depends on BR2_TARGET_OPENSBI_CUSTOM_TARBALL
config BR2_TARGET_OPENSBI_CUSTOM_LOCAL_DIR
string "URL of custom OpenSBI dir"
depends on BR2_TARGET_OPENSBI_CUSTOM_LOCAL
help
$(TOPDIR)/../path/to/your/opensbi-dir,
TOPDIR is your buildroot root dir
if BR2_TARGET_OPENSBI_CUSTOM_GIT
config BR2_TARGET_OPENSBI_CUSTOM_REPO_URL

View file

@ -6,7 +6,10 @@
OPENSBI_VERSION = $(call qstrip,$(BR2_TARGET_OPENSBI_VERSION))
ifeq ($(BR2_TARGET_OPENSBI_CUSTOM_TARBALL),y)
ifeq ($(BR2_TARGET_OPENSBI_CUSTOM_LOCAL),y)
OPENSBI_SITE = $(BR2_TARGET_OPENSBI_CUSTOM_LOCAL_DIR)
OPENSBI_SITE_METHOD = local
else ifeq ($(BR2_TARGET_OPENSBI_CUSTOM_TARBALL),y)
# Handle custom OpenSBI tarballs as specified by the configuration
OPENSBI_TARBALL = $(call qstrip,$(BR2_TARGET_OPENSBI_CUSTOM_TARBALL_LOCATION))
OPENSBI_SITE = $(patsubst %/,%,$(dir $(OPENSBI_TARBALL)))
@ -78,6 +81,8 @@ define OPENSBI_INSTALL_IMAGES_CMDS
$(BINARIES_DIR)/fw_$(f).bin
$(INSTALL) -m 0644 -D $(@D)/build/platform/$(OPENSBI_PLAT)/firmware/fw_$(f).elf \
$(BINARIES_DIR)/fw_$(f).elf
$(INSTALL) -m 0644 -D $(@D)/build/platform/$(OPENSBI_PLAT)/firmware/fw_$(f).itb \
$(BINARIES_DIR)/fw_$(f).itb
)
endef
endif

View file

@ -51,6 +51,9 @@ config BR2_TARGET_UBOOT_CUSTOM_VERSION
config BR2_TARGET_UBOOT_CUSTOM_TARBALL
bool "Custom tarball"
config BR2_TARGET_UBOOT_CUSTOM_DIR
bool "Custom local dir"
config BR2_TARGET_UBOOT_CUSTOM_GIT
bool "Custom Git repository"
@ -70,6 +73,10 @@ config BR2_TARGET_UBOOT_CUSTOM_TARBALL_LOCATION
string "URL of custom U-Boot tarball"
depends on BR2_TARGET_UBOOT_CUSTOM_TARBALL
config BR2_TARGET_UBOOT_CUSTOM_DIR_LOCATION
string "URL of custom U-Boot local dir"
depends on BR2_TARGET_UBOOT_CUSTOM_DIR
if BR2_TARGET_UBOOT_CUSTOM_GIT || BR2_TARGET_UBOOT_CUSTOM_HG || BR2_TARGET_UBOOT_CUSTOM_SVN
config BR2_TARGET_UBOOT_CUSTOM_REPO_URL

View file

@ -20,7 +20,10 @@ UBOOT_INSTALL_IMAGES = YES
UBOOT_DEPENDENCIES = host-pkgconf $(BR2_MAKE_HOST_DEPENDENCY)
UBOOT_MAKE = $(BR2_MAKE)
ifeq ($(BR2_TARGET_UBOOT_CUSTOM_TARBALL),y)
ifeq ($(BR2_TARGET_UBOOT_CUSTOM_DIR),y)
UBOOT_SITE = $(BR2_TARGET_UBOOT_CUSTOM_DIR_LOCATION)
UBOOT_SITE_METHOD = local
else ifeq ($(BR2_TARGET_UBOOT_CUSTOM_TARBALL),y)
# Handle custom U-Boot tarballs as specified by the configuration
UBOOT_TARBALL = $(call qstrip,$(BR2_TARGET_UBOOT_CUSTOM_TARBALL_LOCATION))
UBOOT_SITE = $(patsubst %/,%,$(dir $(UBOOT_TARBALL)))

View file

@ -23,6 +23,7 @@ define ROOTFS_CPIO_ADD_INIT
fi
mkdir -p $(TARGET_DIR)/dev
mknod -m 0622 $(TARGET_DIR)/dev/console c 5 1
mknod -m 0622 $(TARGET_DIR)/dev/null c 1 3
endef
endif # BR2_ROOTFS_DEVICE_CREATION_STATIC

View file

@ -15,7 +15,9 @@ do_strip=no
# Dracut modules needed
add_dracutmodules+=" \
busybox-init
busybox-init \
busybox \
rescue \
"
# Modules to ignore
@ -24,7 +26,6 @@ bash \
biosdevname \
btrfs \
bluetooth \
busybox \
caps \
cifs \
crypt \

View file

@ -85,6 +85,11 @@ config BR2_LINUX_KERNEL_CUSTOM_TARBALL
to use a make variable like $(TOPDIR) to reference the root of
the Buildroot tree.
config BR2_LINUX_KERNEL_CUSTOM_DIR
bool "Custom local dir"
help
allows to specify a URL to your local kernel dir
config BR2_LINUX_KERNEL_CUSTOM_GIT
bool "Custom Git repository"
help
@ -94,7 +99,7 @@ config BR2_LINUX_KERNEL_CUSTOM_GIT
config BR2_LINUX_KERNEL_CUSTOM_HG
bool "Custom Mercurial repository"
help
This option allows Buildroot to get the Linux kernel source
This option allows Buildroot to get the Linux kernel source
code from a Mercurial repository.
config BR2_LINUX_KERNEL_CUSTOM_SVN
@ -113,6 +118,15 @@ config BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION
string "URL of custom kernel tarball"
depends on BR2_LINUX_KERNEL_CUSTOM_TARBALL
config BR2_LINUX_KERNEL_CUSTOM_DIR_LOCATION
string "URL of custom kernel local dir"
depends on BR2_LINUX_KERNEL_CUSTOM_DIR
help
example: $(TOPDIR)/../to/your/kernel-dir
$(TOPDIR) to reference the root of
the Buildroot tree.
if BR2_LINUX_KERNEL_CUSTOM_GIT || BR2_LINUX_KERNEL_CUSTOM_HG || BR2_LINUX_KERNEL_CUSTOM_SVN
config BR2_LINUX_KERNEL_CUSTOM_REPO_URL
@ -134,6 +148,7 @@ config BR2_LINUX_KERNEL_VERSION
default BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE \
if BR2_LINUX_KERNEL_CUSTOM_VERSION
default "custom" if BR2_LINUX_KERNEL_CUSTOM_TARBALL
default "custom" if BR2_LINUX_KERNEL_CUSTOM_DIR
default BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION \
if BR2_LINUX_KERNEL_CUSTOM_GIT || BR2_LINUX_KERNEL_CUSTOM_HG || BR2_LINUX_KERNEL_CUSTOM_SVN

View file

@ -17,7 +17,10 @@ LINUX_CPE_ID_PRODUCT = linux_kernel
LINUX_CPE_ID_PREFIX = cpe:2.3:o
# Compute LINUX_SOURCE and LINUX_SITE from the configuration
ifeq ($(BR2_LINUX_KERNEL_CUSTOM_TARBALL),y)
ifeq ($(BR2_LINUX_KERNEL_CUSTOM_DIR),y)
LINUX_SITE = $(BR2_LINUX_KERNEL_CUSTOM_DIR_LOCATION)
LINUX_SITE_METHOD = local
else ifeq ($(BR2_LINUX_KERNEL_CUSTOM_TARBALL),y)
LINUX_TARBALL = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION))
LINUX_SITE = $(patsubst %/,%,$(dir $(LINUX_TARBALL)))
LINUX_SOURCE = $(notdir $(LINUX_TARBALL))

View file

@ -0,0 +1,61 @@
From ab160332a117007df37bfe27abf5802d3db5f235 Mon Sep 17 00:00:00 2001
From: max <guoqun.ma@spacemit.com>
Date: Mon, 22 Jan 2024 10:23:07 +0800
Subject: [PATCH] support chinese
---
libbb/printable_string.c | 5 +++++
libbb/unicode.c | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/libbb/printable_string.c b/libbb/printable_string.c
index a814fd0..65d792e 100644
--- a/libbb/printable_string.c
+++ b/libbb/printable_string.c
@@ -28,8 +28,10 @@ const char* FAST_FUNC printable_string2(uni_stat_t *stats, const char *str)
}
if (c < ' ')
break;
+/*
if (c >= 0x7f)
break;
+*/
s++;
}
@@ -42,7 +44,10 @@ const char* FAST_FUNC printable_string2(uni_stat_t *stats, const char *str)
unsigned char c = *d;
if (c == '\0')
break;
+ /*
if (c < ' ' || c >= 0x7f)
+ */
+ if (c < ' ')
*d = '?';
d++;
}
diff --git a/libbb/unicode.c b/libbb/unicode.c
index e98cbbf..afbcc10 100644
--- a/libbb/unicode.c
+++ b/libbb/unicode.c
@@ -1027,7 +1027,7 @@ static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char
while ((int)--width >= 0);
break;
}
- *d++ = (c >= ' ' && c < 0x7f) ? c : '?';
+ *d++ = (c >= ' ' /* && c < 0x7f */) ? c : '?';
src++;
}
*d = '\0';
@@ -1035,7 +1035,7 @@ static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char
d = dst = xstrndup(src, width);
while (*d) {
unsigned char c = *d;
- if (c < ' ' || c >= 0x7f)
+ if (c < ' ' /* || c >= 0x7f */)
*d = '?';
d++;
}
--
2.25.1

View file

@ -0,0 +1,90 @@
From 65af285e2b025d93fb44147d26dbf4c00dda2a23 Mon Sep 17 00:00:00 2001
From: max <guoqun.ma@spacemit.com>
Date: Wed, 24 Jan 2024 16:07:20 +0800
Subject: [PATCH] support reboot to bootloader
---
init/halt.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/init/halt.c b/init/halt.c
index fe3cb9e..9118e7a 100644
--- a/init/halt.c
+++ b/init/halt.c
@@ -93,6 +93,20 @@
#include "libbb.h"
#include "reboot.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/reboot.h>
+#include <sys/types.h>
+#include <linux/reboot.h>
+#include <sys/syscall.h>
+
+#define LINUX_REBOOT_MAGIC1 0xfee1dead
+#define LINUX_REBOOT_MAGIC2 672274793
+#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
#if ENABLE_FEATURE_WTMP
#include <sys/utsname.h>
@@ -162,13 +176,14 @@ static int init_was_not_there(void)
#endif
int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int halt_main(int argc UNUSED_PARAM, char **argv)
+int halt_main(int argc , char **argv)
{
static const int magic[] = {
RB_HALT_SYSTEM,
RB_POWER_OFF,
RB_AUTOBOOT
};
+
static const smallint signals[] = { SIGUSR1, SIGUSR2, SIGTERM };
int delay = 0;
@@ -187,6 +202,36 @@ int halt_main(int argc UNUSED_PARAM, char **argv)
for (which = 0; "hpr"[which] != applet_name[0]; which++)
continue;
+ if((argc == 1) ||(argc != 1 && !strcmp(argv[1],"bootloader"))) {
+ char buf[100];
+ int pid, ret;
+
+ sync();
+
+ /* Attempt to unmount the SD card first.
+ * No need to bother checking for errors.
+ */
+ pid = fork();
+ if (pid == 0) {
+ /* ask vdc to unmount it */
+ /*execl("/system/bin/vdc", "/system/bin/vdc", "volume", "unmount",
+ getenv("EXTERNAL_STORAGE"), "force", NULL);*/
+ } else if (pid > 0) {
+ /* wait until vdc succeeds or fails */
+ waitpid(pid, &ret, 0);
+ }
+
+ if(argc == 1)
+ ret = reboot(magic[which]);
+ else
+ ret = syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART2, argv[1]);
+ if (ret < 0) {
+ snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
+ }
+
+ }
+
/* Parse and handle arguments */
/* We support -w even if !ENABLE_FEATURE_WTMP,
* in order to not break scripts.
--
2.25.1

View file

@ -55,5 +55,6 @@ install() {
/etc/group \
/etc/passwd \
/etc/shadow \
/etc/hostname
/etc/hostname \
/lib/firmware/esos.elf
}

View file

@ -43,6 +43,8 @@ ifeq ($(BR2_INIT_BUSYBOX),y)
define HOST_DRACUT_POST_INSTALL_BUSYBOX_INIT_MODULE
$(INSTALL) -D -m 0755 package/dracut/busybox-init-module-setup.sh \
$(HOST_DIR)/lib/dracut/modules.d/05busybox-init/module-setup.sh
$(INSTALL) -D -m 0755 package/dracut/rescue-module-setup.sh \
$(HOST_DIR)/lib/dracut/modules.d/03rescue/module-setup.sh
endef
HOST_DRACUT_POST_INSTALL_HOOKS += HOST_DRACUT_POST_INSTALL_BUSYBOX_INIT_MODULE
endif

View file

@ -0,0 +1,19 @@
#!/bin/bash
# called by dracut
check() {
# do not add this module by default
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
install() {
inst_multiple -o ps grep more cat rm strace free showmount \
ping netstat rpcinfo vi scp ping6 ssh \
fsck fsck.ext2 fsck.ext4 fsck.ext3 fsck.ext4dev fsck.f2fs fsck.vfat e2fsck resize2fs mount
}

View file

@ -1,44 +0,0 @@
From 09b536e0b9d0964674936901ab9d2954f935c8b4 Mon Sep 17 00:00:00 2001
From: Stefan Ott <stefan@ott.net>
Date: Wed, 5 Apr 2023 18:20:37 +0200
Subject: [PATCH] Fix compile-time issue on very old kernels
Kernel versions prior to 3.4 did not have V4L2_CAP_DEVICE_CAPS and
compiling against such a kernel will fail.
This patch introduces a version check and makes eudev fall back to
v2cap.capabilities on these kernels.
Upstream: https://github.com/eudev-project/eudev/commit/09b536e0b9d0964674936901ab9d2954f935c8b4
Signed-off-by: Stefan Ott <stefan@ott.net>
---
src/v4l_id/v4l_id.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/v4l_id/v4l_id.c b/src/v4l_id/v4l_id.c
index 6bf45effe..702d5b687 100644
--- a/src/v4l_id/v4l_id.c
+++ b/src/v4l_id/v4l_id.c
@@ -28,6 +28,7 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
+#include <linux/version.h>
#include <linux/videodev2.h>
#include "util.h"
@@ -71,9 +72,11 @@ int main(int argc, char *argv[]) {
printf("ID_V4L_VERSION=2\n");
printf("ID_V4L_PRODUCT=%s\n", v2cap.card);
printf("ID_V4L_CAPABILITIES=:");
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
if (v2cap.capabilities & V4L2_CAP_DEVICE_CAPS)
capabilities = v2cap.device_caps;
else
+#endif
capabilities = v2cap.capabilities;
if ((capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0 ||
(capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) > 0)
--
2.40.0

View file

@ -16,7 +16,7 @@ config BR2_PACKAGE_EUDEV
Upstart, older kernels, various toolchains and anything else
required by users and various distributions.
https://github.com/eudev-project/eudev
https://wiki.gentoo.org/wiki/Project:Eudev
if BR2_PACKAGE_EUDEV

View file

@ -21,13 +21,72 @@ UDEV_CONFIG=/etc/udev/udev.conf
test -r $UDEV_CONFIG || exit 6
. $UDEV_CONFIG
# we need to unmount /dev/pts/ and remount it later over the devtmpfs
unmount_devpts() {
if mountpoint -q /dev/pts/; then
umount -n -l /dev/pts/
fi
if mountpoint -q /dev/shm/; then
umount -n -l /dev/shm/
fi
}
# mount a devtmpfs over /dev, if somebody did not already do it
mount_devtmpfs() {
if grep -E -q "^[^[:space:]]+ /dev devtmpfs" /proc/mounts; then
mount -n -o remount,nosuid,mode=0755 -t devtmpfs devtmpfs /dev
return
fi
if ! mount -n -o nosuid,mode=0755 -t devtmpfs devtmpfs /dev; then
echo "udev requires devtmpfs support, not started"
fi
return 0
}
create_dev_makedev() {
if [ -e /sbin/MAKEDEV ]; then
ln -sf /sbin/MAKEDEV /dev/MAKEDEV
else
ln -sf /bin/true /dev/MAKEDEV
fi
}
make_static_nodes() {
[ -e /lib/modules/$(uname -r)/modules.devname ] || return 0
[ -x /usr/bin/kmod ] || return 0
/usr/bin/kmod static-nodes --format=tmpfiles --output=/proc/self/fd/1 | \
while read type name mode uid gid age arg; do
[ -e $name ] && continue
case "$type" in
c|b|c!|b!) mknod -m $mode $name $type $(echo $arg | sed 's/:/ /') ;;
d|d!) mkdir $name ;;
*) echo "unparseable line ($type $name $mode $uid $gid $age $arg)" >&2 ;;
esac
done
}
case "$1" in
start)
if ! mountpoint -q /dev/; then
unmount_devpts
mount_devtmpfs
fi
make_static_nodes
# clean up parts of the database created by the initramfs udev
udevadm info --cleanup-db
printf "Populating %s using udev: " "${udev_root:-/dev}"
[ -e /proc/sys/kernel/hotplug ] && printf '\000\000\000\000' > /proc/sys/kernel/hotplug
/sbin/udevd -d || { echo "FAIL"; exit 1; }
udevadm trigger --type=subsystems --action=add
udevadm trigger --type=devices --action=add
create_dev_makedev
udevadm settle --timeout=30 || echo "udevadm settle failed"
echo "done"
;;

View file

@ -1,3 +1,5 @@
# From http://dev.gentoo.org/~blueness/eudev/
md5 60b135a189523f333cea5f71a3345c8d eudev-3.2.10.tar.gz
# Locally calculated
sha256 19847cafec67897da855fde56f9dc7d92e21c50e450aa79068a7e704ed44558b eudev-3.2.11.tar.gz
sha256 87bb028d470fd1b85169349b44c55d5b733733dc2d50ddf1196e026725ead034 eudev-3.2.10.tar.gz
sha256 ab15fd526bd8dd18a9e77ebc139656bf4d33e97fc7238cd11bf60e2b9b8666c6 COPYING

View file

@ -4,8 +4,8 @@
#
################################################################################
EUDEV_VERSION = 3.2.11
EUDEV_SITE = https://github.com/eudev-project/eudev/releases/download/v$(EUDEV_VERSION)
EUDEV_VERSION = 3.2.10
EUDEV_SITE = http://dev.gentoo.org/~blueness/eudev
EUDEV_LICENSE = GPL-2.0+ (programs), LGPL-2.1+ (libraries)
EUDEV_LICENSE_FILES = COPYING
EUDEV_INSTALL_STAGING = YES
@ -57,12 +57,13 @@ endef
HOST_EUDEV_DEPENDENCIES = host-gperf host-pkgconf
HOST_EUDEV_SYSCONFDIR = $(if $(BR2_PACKAGE_SYSTEMD),/usr/lib,/etc)
HOST_EUDEV_CONF_OPTS = \
--prefix=/usr \
--sbindir=/sbin \
--libexecdir=/lib \
--with-rootlibdir=/lib \
--sysconfdir=/etc \
--sysconfdir=$(HOST_EUDEV_SYSCONFDIR) \
--disable-blkid \
--disable-introspection \
--disable-kmod \
@ -81,5 +82,13 @@ define HOST_EUDEV_BUILD_HWDB
endef
HOST_EUDEV_TARGET_FINALIZE_HOOKS += HOST_EUDEV_BUILD_HWDB
# Note: this will run in the filesystem context, so will use a copy
# of tharget/, not the real one, so the files are still available on
# re-builds (foo-rebuild, etc...)
define HOST_EUDEV_RM_HWDB_SRC
rm -rf $(TARGET_DIR)/$(HOST_EUDEV_SYSCONFDIR)/udev/hwdb.d/
endef
HOST_EUDEV_ROOTFS_PRE_CMD_HOOKS += HOST_EUDEV_RM_HWDB_SRC
$(eval $(autotools-package))
$(eval $(host-autotools-package))

View file

@ -0,0 +1,658 @@
From ad231da546c0680c5895fc7a31d52a6e4af966da Mon Sep 17 00:00:00 2001
From: fuqiang <qiang.fu@spacemit.com>
Date: Tue, 26 Dec 2023 20:01:37 +0800
Subject: [PATCH] support spacemit mpp
---
configure | 6 +-
libavcodec/Makefile | 2 +
libavcodec/allcodecs.c | 2 +
libavcodec/stcodecdec.c | 553 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 562 insertions(+), 1 deletion(-)
create mode 100755 libavcodec/stcodecdec.c
diff --git a/configure b/configure
index 01bb1dd..52561c1 100755
--- a/configure
+++ b/configure
@@ -345,6 +345,7 @@ External library support:
--enable-omx enable OpenMAX IL code [no]
--enable-omx-rpi enable OpenMAX IL code for Raspberry Pi [no]
--enable-rkmpp enable Rockchip Media Process Platform code [no]
+ --enable-stcodec enable Spacemit Media Process Platform code [no]
--disable-v4l2-m2m disable V4L2 mem2mem code [autodetect]
--disable-vaapi disable Video Acceleration API (mainly Unix/Intel) code [autodetect]
--disable-vdpau disable Nvidia Video Decode and Presentation API for Unix code [autodetect]
@@ -1730,6 +1731,7 @@ EXTERNAL_LIBRARY_GPL_LIST="
libxavs
libxavs2
libxvid
+ stcodec
"
EXTERNAL_LIBRARY_NONFREE_LIST="
@@ -3092,6 +3094,7 @@ h264_vaapi_encoder_select="cbs_h264 vaapi_encode"
h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m"
h264_v4l2m2m_decoder_select="h264_mp4toannexb_bsf"
h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m"
+h264_stcodec_decoder_deps="stcodec"
hevc_amf_encoder_deps="amf"
hevc_cuvid_decoder_deps="cuvid"
hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf"
@@ -3109,6 +3112,7 @@ hevc_vaapi_encoder_select="cbs_h265 vaapi_encode"
hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m"
hevc_v4l2m2m_decoder_select="hevc_mp4toannexb_bsf"
hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m"
+hevc_stcodec_decoder_deps="stcodec"
mjpeg_cuvid_decoder_deps="cuvid"
mjpeg_qsv_decoder_select="qsvdec"
mjpeg_qsv_encoder_deps="libmfx"
@@ -6547,7 +6551,7 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r
die "ERROR: rkmpp requires --enable-libdrm"; }
}
enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init
-
+enabled stcodec
if enabled gcrypt; then
GCRYPT_CONFIG="${cross_prefix}libgcrypt-config"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index b3d284d..ff56ed6 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -385,6 +385,7 @@ OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o
OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
+OBJS-$(CONFIG_H264_STCODEC_DECODER) += stcodecdec.o
OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o
OBJS-$(CONFIG_HCA_DECODER) += hcadec.o
@@ -405,6 +406,7 @@ OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o
OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o
OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
+OBJS-$(CONFIG_HEVC_STCODEC_DECODER) += stcodecdec.o
OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o
OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \
canopus.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 2e9a358..9981106 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -148,11 +148,13 @@ extern AVCodec ff_h264_mediacodec_decoder;
extern AVCodec ff_h264_mmal_decoder;
extern AVCodec ff_h264_qsv_decoder;
extern AVCodec ff_h264_rkmpp_decoder;
+extern AVCodec ff_h264_stcodec_decoder;
extern AVCodec ff_hap_encoder;
extern AVCodec ff_hap_decoder;
extern AVCodec ff_hevc_decoder;
extern AVCodec ff_hevc_qsv_decoder;
extern AVCodec ff_hevc_rkmpp_decoder;
+extern AVCodec ff_hevc_stcodec_decoder;
extern AVCodec ff_hevc_v4l2m2m_decoder;
extern AVCodec ff_hnm4_video_decoder;
extern AVCodec ff_hq_hqa_decoder;
diff --git a/libavcodec/stcodecdec.c b/libavcodec/stcodecdec.c
new file mode 100755
index 0000000..763e1b2
--- /dev/null
+++ b/libavcodec/stcodecdec.c
@@ -0,0 +1,553 @@
+/*
+ * Spacemit MPP Video Decoder
+ * Copyright 2022-2023 SPACEMIT. All rights reserved.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <drm_fourcc.h>
+#include <pthread.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "avcodec.h"
+#include "internal.h"
+#include "decode.h"
+#include "h264_parse.h"
+#include "hevc_parse.h"
+#include "hwconfig.h"
+#include "libavutil/buffer.h"
+#include "libavutil/common.h"
+#include "libavutil/frame.h"
+#include "libavutil/hwcontext.h"
+#include "libavutil/hwcontext_drm.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/log.h"
+#include "vdec.h"
+
+#define PACKET_SIZE (2 * 1024 * 1024)
+
+typedef struct {
+ MppVdecCtx* pVdecCtx;
+ MppVdecPara* pVdecPara;
+ MppPacket* pPacket;
+ MppFrame* pFrame;
+ enum AVPixelFormat ePixFmt;
+
+ char eos_reached;
+
+ AVBufferRef* frames_ref;
+ AVBufferRef* device_ref;
+} STCODECDecoder;
+
+typedef struct {
+ AVClass* av_class;
+ AVBufferRef* decoder_ref;
+} STCODECDecodeContext;
+
+typedef struct {
+ MppFrame* pFrame;
+ AVBufferRef* decoder_ref;
+} STCODECFrameContext;
+
+static MppCodingType stcodec_get_codingtype(AVCodecContext* avctx) {
+ switch (avctx->codec_id) {
+ case AV_CODEC_ID_H264:
+ return CODING_H264;
+ case AV_CODEC_ID_HEVC:
+ return CODING_H265;
+ case AV_CODEC_ID_VP8:
+ return CODING_VP8;
+ case AV_CODEC_ID_VP9:
+ return CODING_VP9;
+ case AV_CODEC_ID_MJPEG:
+ return CODING_MJPEG;
+ default:
+ return CODING_UNKNOWN;
+ }
+}
+
+static int get_stride(int width, int align) {
+ return (width + align - 1) & (~(align - 1));
+}
+
+static int stcodec_send_data_to_decoder(AVCodecContext* avctx, uint8_t* buffer,
+ int size, int64_t pts) {
+ STCODECDecodeContext* st_context = avctx->priv_data;
+ STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data;
+ int ret = 0;
+
+ if (!buffer && 0 == size) {
+ // a NULL packet, need to send EOS to decoder.
+ PACKET_SetEos(decoder->pPacket, 1);
+ PACKET_SetLength(decoder->pPacket, 0);
+ } else {
+ // debug
+ av_log(avctx, AV_LOG_DEBUG, "%x %x %x %x %x length = %d\n", *buffer,
+ *(buffer + 1), *(buffer + 2), *(buffer + 3), *(buffer + 4), size);
+
+ PACKET_SetDataPointer(decoder->pPacket, buffer);
+ PACKET_SetLength(decoder->pPacket, size);
+ PACKET_SetPts(decoder->pPacket, pts);
+ PACKET_SetEos(decoder->pPacket, 0);
+ av_log(avctx, AV_LOG_DEBUG, "input pts : %ld\n", pts);
+ }
+
+ // send packet to decoder, the packet will be copyed in decoder, so can
+ // release it here.
+ ret = VDEC_Decode(decoder->pVdecCtx, PACKET_GetBaseData(decoder->pPacket));
+ if (ret) {
+ if (ret == MPP_DATAQUEUE_FULL) {
+ // input unblock mode will go here.
+ av_log(avctx, AV_LOG_DEBUG, "Buffer full writing %d bytes to decoder\n",
+ size);
+ ret = AVERROR(EAGAIN); // here something wrong, maybe return 0
+ } else {
+ ret = AVERROR_UNKNOWN;
+ }
+ } else {
+ av_log(avctx, AV_LOG_DEBUG, "Write %d bytes to decoder\n", size);
+ }
+
+ return ret; // here something wrong, maybe return 0
+}
+
+static int stcodec_close_decoder(AVCodecContext* avctx) {
+ STCODECDecodeContext* st_context = avctx->priv_data;
+ av_log(NULL, AV_LOG_DEBUG, "stcodec close decoder\n");
+ av_buffer_unref(&st_context->decoder_ref);
+ return 0;
+}
+
+static void stcodec_release_stcodec_decoder(void* opaque, uint8_t* data) {
+ STCODECDecoder* decoder = (STCODECDecoder*)data;
+ if (decoder->pVdecCtx) {
+ av_log(NULL, AV_LOG_ERROR, "stcodec release decoder\n");
+ VDEC_ResetChannel(decoder->pVdecCtx);
+ VDEC_DestoryChannel(decoder->pVdecCtx);
+ decoder->pVdecCtx = NULL;
+ }
+ av_buffer_unref(&decoder->frames_ref);
+ av_buffer_unref(&decoder->device_ref);
+ av_free(decoder);
+}
+
+static int stcodec_init_decoder(AVCodecContext* avctx) {
+ STCODECDecodeContext* st_context = avctx->priv_data;
+ STCODECDecoder* decoder = NULL;
+ MppCodingType codectype = CODING_UNKNOWN;
+ int ret;
+/*
+ if (avctx->width > 4096 || avctx->height > 2160 || avctx->width <= 640 ||
+ avctx->height <= 480) {
+ av_log(avctx, AV_LOG_ERROR,
+ "STCODEC Decoder do not support the size (%d x %d), too big or too "
+ "small!\n",
+ avctx->width, avctx->height);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+*/
+ avctx->pix_fmt = ff_get_format(avctx, avctx->codec->pix_fmts);
+ av_log(avctx, AV_LOG_ERROR, "------------------------ Use pixel format %d\n", avctx->pix_fmt);
+
+ // create a decoder and a ref to it
+ decoder = av_mallocz(sizeof(STCODECDecoder));
+ if (!decoder) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to av_mallocz STCODECDecoder\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ decoder->ePixFmt = avctx->pix_fmt;
+
+ st_context->decoder_ref = av_buffer_create(
+ (uint8_t*)decoder, sizeof(*decoder), stcodec_release_stcodec_decoder,
+ NULL, AV_BUFFER_FLAG_READONLY);
+ if (!st_context->decoder_ref) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create ref of STCODECDecoder!\n");
+ av_free(decoder);
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ av_log(avctx, AV_LOG_DEBUG, "Initializing STCODEC decoder.\n");
+
+ codectype = stcodec_get_codingtype(avctx);
+ if (CODING_UNKNOWN == codectype) {
+ av_log(avctx, AV_LOG_ERROR, "Unknown codec type (%d).\n", avctx->codec_id);
+ av_free(decoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ // Create the MPP context
+ decoder->pVdecCtx = VDEC_CreateChannel();
+ if (!decoder->pVdecCtx) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create STCODEC VDEC channel.\n");
+ av_free(decoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ // set para
+ decoder->pVdecCtx->stVdecPara.eCodingType = codectype;
+ decoder->pVdecCtx->stVdecPara.bInputBlockModeEnable = MPP_FALSE;
+ decoder->pVdecCtx->stVdecPara.bOutputBlockModeEnable = MPP_TRUE;
+ decoder->pVdecCtx->stVdecPara.nWidth = avctx->width;
+ decoder->pVdecCtx->stVdecPara.nHeight = avctx->height;
+ decoder->pVdecCtx->stVdecPara.nStride = get_stride(avctx->width, 8);
+ decoder->pVdecCtx->stVdecPara.eOutputPixelFormat = PIXEL_FORMAT_NV12;
+ decoder->pVdecCtx->eCodecType = CODEC_V4L2_LINLONV5V7;
+ decoder->pVdecCtx->stVdecPara.nScale = 1;
+ decoder->pVdecCtx->stVdecPara.nHorizonScaleDownRatio = 1;
+ decoder->pVdecCtx->stVdecPara.nVerticalScaleDownRatio = 1;
+ decoder->pVdecCtx->stVdecPara.nRotateDegree = 0;
+ decoder->pVdecCtx->stVdecPara.bThumbnailMode = 0;
+ decoder->pVdecCtx->stVdecPara.bIsInterlaced = MPP_FALSE;
+
+ // vdec init
+ ret = VDEC_Init(decoder->pVdecCtx);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to initialize STCODEC VDEV (ret = %d).\n", ret);
+ VDEC_DestoryChannel(decoder->pVdecCtx);
+ av_free(decoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ av_log(avctx, AV_LOG_ERROR, "init 1.\n");
+ // mpp packet init
+ decoder->pPacket = PACKET_Create();
+ if (!decoder->pPacket) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to initialize STCODEC packet.\n");
+ VDEC_DestoryChannel(decoder->pVdecCtx);
+ av_free(decoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+ PACKET_Alloc(decoder->pPacket, PACKET_SIZE);
+
+ av_log(avctx, AV_LOG_ERROR, "init 2.\n");
+ // mpp frame init
+ decoder->pFrame = FRAME_Create();
+ if (!decoder->pFrame) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to initialize STCODEC frame.\n");
+ PACKET_Destory(decoder->pPacket);
+ VDEC_DestoryChannel(decoder->pVdecCtx);
+ av_free(decoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ av_log(avctx, AV_LOG_ERROR, "init 3.\n");
+ av_log(avctx, AV_LOG_DEBUG, "STCODEC decoder initialized successfully.\n");
+
+ decoder->device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_DRM);
+ if (!decoder->device_ref) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to av_hwdevice_ctx_alloc\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ av_log(avctx, AV_LOG_ERROR, "init 4.\n");
+ ret = av_hwdevice_ctx_init(decoder->device_ref);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to av_hwdevice_ctx_init\n");
+ goto fail;
+ }
+ av_log(avctx, AV_LOG_ERROR, "init 5.\n");
+
+ decoder->frames_ref = av_hwframe_ctx_alloc(decoder->device_ref);
+ if (!decoder->frames_ref) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to av_hwframe_ctx_alloc\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ av_log(avctx, AV_LOG_ERROR, "init 6.\n");
+
+ AVHWFramesContext* hwframes;
+ hwframes = (AVHWFramesContext*)decoder->frames_ref->data;
+ hwframes->format = AV_PIX_FMT_DRM_PRIME;
+ hwframes->sw_format = AV_PIX_FMT_NV12;
+ hwframes->width = avctx->width;
+ hwframes->height = avctx->height;
+ ret = av_hwframe_ctx_init(decoder->frames_ref);
+ if (ret < 0) goto fail;
+
+ av_log(avctx, AV_LOG_DEBUG, "Initialized successfully.\n");
+ av_log(avctx, AV_LOG_ERROR, "init 7.\n");
+ return 0;
+
+fail:
+ av_log(avctx, AV_LOG_ERROR, "init 8.\n");
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to initialize STCODEC decoder, please check!\n");
+ stcodec_close_decoder(avctx);
+ return ret;
+}
+
+static int stcodec_send_packet(AVCodecContext* avctx, const AVPacket* avpkt) {
+ STCODECDecodeContext* st_context = avctx->priv_data;
+ STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data;
+ int ret;
+ av_log(avctx, AV_LOG_DEBUG, "start send packet, pts(%ld)\n", avpkt->pts);
+
+ // handle EOF
+ if (!avpkt->size) {
+ av_log(avctx, AV_LOG_ERROR, "Get EOS from parser!\n");
+ decoder->eos_reached = 1;
+ // write a NULL data to decoder to inform it the EOS.
+ ret = stcodec_send_data_to_decoder(avctx, NULL, 0, 0);
+ if (ret)
+ av_log(avctx, AV_LOG_ERROR, "Failed to send EOS to decoder (ret = %d)\n",
+ ret);
+ return ret;
+ }
+
+ // now send packet
+ ret =
+ stcodec_send_data_to_decoder(avctx, avpkt->data, avpkt->size, avpkt->pts);
+ if (ret) {
+ av_log(avctx, AV_LOG_DEBUG,
+ "Failed to write data to decoder (code = %d (%s))\n", ret,
+ av_err2str(ret));
+ } else {
+ av_log(avctx, AV_LOG_DEBUG,
+ "OK! Write data to decoder, (size = %d) (ret = %d)\n", avpkt->size,
+ ret);
+ }
+
+ return ret;
+}
+
+static void stcodec_release_frame(void* opaque, uint8_t* data) {
+ AVDRMFrameDescriptor* desc = (AVDRMFrameDescriptor*)data;
+ AVBufferRef* framecontextref = (AVBufferRef*)opaque;
+ STCODECFrameContext* framecontext =
+ (STCODECFrameContext*)framecontextref->data;
+
+ av_log(NULL, AV_LOG_DEBUG, "stcodec release frame\n");
+
+ VDEC_ReturnOutputFrame(
+ ((STCODECDecoder*)framecontext->decoder_ref->data)->pVdecCtx,
+ FRAME_GetBaseData(framecontext->pFrame));
+
+ if (((STCODECDecoder*)framecontext->decoder_ref->data)->ePixFmt ==
+ AV_PIX_FMT_DRM_PRIME) {
+ av_free(desc);
+ }
+ av_buffer_unref(&framecontext->decoder_ref);
+ av_buffer_unref(&framecontextref);
+}
+
+static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
+ STCODECDecodeContext* st_context = avctx->priv_data;
+ STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data;
+ AVPacket pkt = {0};
+ int freeslots;
+ STCODECFrameContext* framecontext = NULL;
+ AVBufferRef* framecontextref = NULL;
+ MppFrame* mppframe = FRAME_Create();
+ AVDRMFrameDescriptor* desc = NULL;
+ AVDRMLayerDescriptor* layer = NULL;
+ int ret = -1;
+
+ av_log(avctx, AV_LOG_DEBUG, "start receive frame\n");
+
+ if (!decoder->eos_reached) {
+ // we get the available input queue num in decoder
+ VDEC_GetParam(decoder->pVdecCtx, &(decoder->pVdecPara));
+ freeslots = decoder->pVdecPara->nInputQueueLeftNum;
+ av_log(avctx, AV_LOG_ERROR, "--------- Input queue left %d seat!!\n", freeslots);
+
+ if (freeslots > 0) {
+ ret = ff_decode_get_packet(avctx, &pkt);
+ if (ret < 0 && ret != AVERROR_EOF) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to ff_decode_get_packet (ret = %d (%s))\n", ret,
+ av_err2str(ret));
+ return ret;
+ }
+
+ ret = stcodec_send_packet(avctx, &pkt);
+ av_packet_unref(&pkt);
+
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to send packet to decoder (code = %d (%s))\n", ret,
+ av_err2str(ret));
+ return ret;
+ }
+ }
+
+ // make sure we keep decoder full
+ VDEC_GetParam(decoder->pVdecCtx, &(decoder->pVdecPara));
+ freeslots = decoder->pVdecPara->nInputQueueLeftNum;
+ av_log(avctx, AV_LOG_ERROR, "========== Input queue left %d seat!!\n", freeslots);
+ if (freeslots > 0) return AVERROR(EAGAIN);
+ }
+
+ ret = VDEC_RequestOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
+ av_log(avctx, AV_LOG_DEBUG, "Request frame (ret = %d)\n", ret);
+
+ if (ret == MPP_CODER_EOS && mppframe == NULL) {
+ av_log(avctx, AV_LOG_ERROR, "EOS 1!\n");
+ return AVERROR_EOF;
+ }
+
+ if (ret == MPP_CODER_EOS ||
+ FRAME_GetEos(mppframe) == 1 /* || decoder->eos_reached*/) {
+ av_log(avctx, AV_LOG_ERROR, "EOS 2!\n");
+ VDEC_ReturnOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
+ return AVERROR_EOF;
+ }
+
+ if (!ret) {
+ av_log(NULL, AV_LOG_DEBUG, "stcodec request a frame\n");
+
+ // setup general frame fields
+ frame->format = avctx->pix_fmt;
+ frame->width = avctx->width;
+ frame->height = avctx->height;
+ // frame->pts = FRAME_GetPts(decoder->pFrame);
+ frame->interlaced_frame = 0;
+ frame->top_field_first = 0;
+
+ framecontextref = av_buffer_allocz(sizeof(*framecontext));
+ if (!framecontextref) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to alloc AvBufferRef\n");
+ ret = AVERROR(ENOMEM);
+ return ret;
+ }
+
+ // MPP decoder needs to be closed only when all frames have been released.
+ framecontext = (STCODECFrameContext*)framecontextref->data;
+ framecontext->decoder_ref = av_buffer_ref(st_context->decoder_ref);
+ framecontext->pFrame = mppframe;
+
+ if (avctx->pix_fmt == AV_PIX_FMT_DRM_PRIME) {
+ desc = av_mallocz(sizeof(AVDRMFrameDescriptor));
+ if (!desc) {
+ ret = AVERROR(ENOMEM);
+ return ret;
+ }
+
+ desc->nb_objects = 1;
+ desc->objects[0].fd = FRAME_GetFD(mppframe, 0);
+ desc->objects[0].size = frame->width * frame->height * 3 / 2;
+ av_log(avctx, AV_LOG_DEBUG, "fd=%d size=%ld\n", desc->objects[0].fd,
+ desc->objects[0].size);
+ desc->nb_layers = 1;
+ layer = &desc->layers[0];
+ layer->format = DRM_FORMAT_NV12;
+ layer->nb_planes = 2;
+
+ layer->planes[0].object_index = 0;
+ layer->planes[0].offset = 0;
+ layer->planes[0].pitch = frame->width;
+
+ layer->planes[1].object_index = 0;
+ layer->planes[1].offset = frame->width * frame->height;
+ layer->planes[1].pitch = frame->width;
+
+ frame->data[0] = (uint8_t*)desc;
+ frame->buf[0] =
+ av_buffer_create((uint8_t*)desc, sizeof(*desc), stcodec_release_frame,
+ framecontextref, AV_BUFFER_FLAG_READONLY);
+ } else if (avctx->pix_fmt == AV_PIX_FMT_NV12) {
+ frame->linesize[0] = get_stride(avctx->width, 8);
+ frame->linesize[1] = get_stride(avctx->width, 8);
+ frame->data[0] = FRAME_GetDataPointer(mppframe, 0);
+ frame->data[1] = frame->data[0] + frame->width * frame->height;
+ frame->buf[0] = av_buffer_create(
+ (uint8_t*)(frame->data[0]), sizeof(frame->data[0]),
+ stcodec_release_frame, framecontextref, AV_BUFFER_FLAG_READONLY);
+ }
+
+ if (!frame->buf[0]) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to create AVDRMFrameDescriptor ref\n");
+ ret = AVERROR(ENOMEM);
+ return ret;
+ }
+
+ frame->hw_frames_ctx = av_buffer_ref(decoder->frames_ref);
+ if (!frame->hw_frames_ctx) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create hw_frames_ctx\n");
+ ret = AVERROR(ENOMEM);
+ return ret;
+ }
+
+ } else {
+ // return AVERROR_UNKNOWN;
+ return AVERROR(EAGAIN);
+ }
+
+ return 0; // return AVERROR(EAGAIN);
+}
+
+static void stcodec_flush(AVCodecContext* avctx) {
+ STCODECDecodeContext* st_context = avctx->priv_data;
+ STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data;
+ int ret = -1;
+
+ av_log(avctx, AV_LOG_ERROR, "Flush.\n");
+/*
+ ret = VDEC_ResetChannel(decoder->pVdecCtx);
+ if (ret)
+ av_log(avctx, AV_LOG_ERROR, "Failed to reset VDEC Channel (code = %d)\n",
+ ret);
+*/
+ decoder->eos_reached = 0;
+}
+
+static const AVCodecHWConfigInternal* const stcodec_hw_configs[] = {
+ HW_CONFIG_INTERNAL(DRM_PRIME), NULL};
+
+#define STCODEC_DEC_CLASS(NAME) \
+ static const AVClass stcodec_##NAME##_dec_class = { \
+ .class_name = "stcodec_" #NAME "_dec", \
+ .version = LIBAVUTIL_VERSION_INT, \
+ };
+
+#define STCODEC_DEC(NAME, ID, BSFS) \
+ STCODEC_DEC_CLASS(NAME) \
+ AVCodec ff_##NAME##_stcodec_decoder = { \
+ .name = #NAME "_stcodec", \
+ .long_name = NULL_IF_CONFIG_SMALL(#NAME " (stcodec decoder)"), \
+ .type = AVMEDIA_TYPE_VIDEO, \
+ .id = ID, \
+ .priv_data_size = sizeof(STCODECDecodeContext), \
+ .init = stcodec_init_decoder, \
+ .close = stcodec_close_decoder, \
+ .receive_frame = stcodec_receive_frame, \
+ .flush = stcodec_flush, \
+ .priv_class = &stcodec_##NAME##_dec_class, \
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | \
+ AV_CODEC_CAP_HARDWARE, \
+ .pix_fmts = \
+ (const enum AVPixelFormat[]){AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_NV12, \
+ AV_PIX_FMT_NONE}, \
+ .hw_configs = stcodec_hw_configs, \
+ .bsfs = BSFS, \
+ .wrapper_name = "stcodec", \
+ };
+
+STCODEC_DEC(h264, AV_CODEC_ID_H264, "h264_mp4toannexb")
+STCODEC_DEC(hevc, AV_CODEC_ID_HEVC, "hevc_mp4toannexb")
+STCODEC_DEC(mjpeg, AV_CODEC_ID_MJPEG, NULL)
--
2.25.1

View file

@ -18,6 +18,7 @@ config BR2_PACKAGE_FFMPEG_ARCH_SUPPORTS
menuconfig BR2_PACKAGE_FFMPEG
bool "ffmpeg"
depends on BR2_PACKAGE_FFMPEG_ARCH_SUPPORTS
select BR2_PACKAGE_MPP
help
FFmpeg is a complete, cross-platform solution to record,
convert and stream audio and video.
@ -32,6 +33,12 @@ config BR2_PACKAGE_FFMPEG_GPL
allow use of GPL code, the resulting libs and binaries will
be under GPL
config BR2_PACKAGE_FFMPEG_SPACEMIT_CODEC
bool "Enable spacemit hardware codec"
depends on BR2_PACKAGE_FFMPEG_GPL
help
allow use of spacemit hardware codec
config BR2_PACKAGE_FFMPEG_NONFREE
bool "Enable nonfree code"
help

View file

@ -66,6 +66,12 @@ else
FFMPEG_CONF_OPTS += --disable-gpl
endif
ifeq ($(BR2_PACKAGE_FFMPEG_SPACEMIT_CODEC),y)
FFMPEG_DEPENDENCIES += mpp
FFMPEG_CONF_OPTS += --extra-libs=-lspacemit_mpp
FFMPEG_CONF_OPTS += --enable-stcodec
endif
ifeq ($(BR2_PACKAGE_FFMPEG_NONFREE),y)
FFMPEG_CONF_OPTS += --enable-nonfree
else

View file

@ -0,0 +1,48 @@
From 67ac4d9efb240a9179e056efd79ba5c5ee436c5e Mon Sep 17 00:00:00 2001
From: dengbo <bo.deng@spacemit.com>
Date: Tue, 21 Nov 2023 20:09:24 +0800
Subject: [PATCH] fix compatibility with python-3.11
---
waflib/ConfigSet.py | 2 +-
waflib/Context.py | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/waflib/ConfigSet.py b/waflib/ConfigSet.py
index 16142a2..87de4ad 100644
--- a/waflib/ConfigSet.py
+++ b/waflib/ConfigSet.py
@@ -140,7 +140,7 @@ class ConfigSet(object):
Utils.writef(filename,''.join(buf))
def load(self,filename):
tbl=self.table
- code=Utils.readf(filename,m='rU')
+ code=Utils.readf(filename,m='r')
for m in re_imp.finditer(code):
g=m.group
tbl[g(2)]=eval(g(3))
diff --git a/waflib/Context.py b/waflib/Context.py
index 8f2cbfb..77f310e 100644
--- a/waflib/Context.py
+++ b/waflib/Context.py
@@ -109,7 +109,7 @@ class Context(ctx):
cache[node]=True
self.pre_recurse(node)
try:
- function_code=node.read('rU',encoding)
+ function_code=node.read('r',encoding)
exec(compile(function_code,node.abspath(),'exec'),self.exec_dict)
finally:
self.post_recurse(node)
@@ -340,7 +340,7 @@ def load_module(path,encoding=None):
pass
module=imp.new_module(WSCRIPT_FILE)
try:
- code=Utils.readf(path,m='rU',encoding=encoding)
+ code=Utils.readf(path,m='r',encoding=encoding)
except EnvironmentError:
raise Errors.WafError('Could not read the file %r'%path)
module_dir=os.path.dirname(path)
--
2.34.1

View file

@ -10,9 +10,6 @@ GLMARK2_LICENSE = GPL-3.0+, SGIv1
GLMARK2_LICENSE_FILES = COPYING COPYING.SGI
GLMARK2_DEPENDENCIES = host-pkgconf jpeg libegl libpng
# The bundled waf script is too old for >= python3.11
GLMARK2_NEEDS_EXTERNAL_WAF = YES
ifeq ($(BR2_PACKAGE_GLMARK2_FLAVOR_DRM_GLESV2),y)
GLMARK2_DEPENDENCIES += libdrm libgbm libgles udev
GLMARK2_FLAVORS += drm-glesv2

View file

@ -0,0 +1,92 @@
From 3dda0a2fff3346dce61cec8db864fd493c775e61 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Tue, 13 Jun 2017 15:52:44 +0100
Subject: [PATCH 1/3] libsync: add support for pre-v4.7 kernels
Add support for the the sync merge ioctl supported by older kernels.
---
libsync.h | 44 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 41 insertions(+), 3 deletions(-)
diff --git a/libsync.h b/libsync.h
index f1a2f96d..c3b8a385 100644
--- a/libsync.h
+++ b/libsync.h
@@ -40,6 +40,10 @@
extern "C" {
#endif
+#ifndef SYNC_IOC_MAGIC
+#define SYNC_IOC_MAGIC '>'
+#endif
+
#ifndef SYNC_IOC_MERGE
/* duplicated from linux/sync_file.h to avoid build-time dependency
* on new (v4.7) kernel headers. Once distro's are mostly using
@@ -53,10 +57,22 @@ struct sync_merge_data {
uint32_t flags;
uint32_t pad;
};
-#define SYNC_IOC_MAGIC '>'
#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
#endif
+#ifndef SYNC_IOC_LEGACY_MERGE
+/* the legacy definitions are based on the contents of
+ * drivers/staging/android/uapi/sync.h in the v4.4 kernel.
+ */
+struct sync_legacy_merge_data {
+ int32_t fd2;
+ char name[32];
+ int32_t fence;
+};
+
+#define SYNC_IOC_LEGACY_MERGE _IOWR(SYNC_IOC_MAGIC, 1, \
+ struct sync_legacy_merge_data)
+#endif
static inline int sync_wait(int fd, int timeout)
{
@@ -83,6 +99,24 @@ static inline int sync_wait(int fd, int timeout)
return ret;
}
+static inline int sync_legacy_merge(const char *name, int fd1, int fd2)
+{
+ struct sync_legacy_merge_data data;
+ int ret;
+
+ data.fd2 = fd2;
+ strncpy(data.name, name, sizeof(data.name));
+
+ do {
+ ret = ioctl(fd1, SYNC_IOC_LEGACY_MERGE, &data);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0)
+ return ret;
+
+ return data.fence;
+}
+
static inline int sync_merge(const char *name, int fd1, int fd2)
{
struct sync_merge_data data = {0};
@@ -95,8 +129,12 @@ static inline int sync_merge(const char *name, int fd1, int fd2)
ret = ioctl(fd1, SYNC_IOC_MERGE, &data);
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ if (errno == ENOTTY)
+ return sync_legacy_merge(name, fd1, fd2);
+ else
+ return ret;
+ }
return data.fence;
}
--
2.34.1

View file

@ -1,43 +0,0 @@
From c9036706b9f724f09ac6288f82b53f2e76264ec7 Mon Sep 17 00:00:00 2001
From: Peter Seiderer <ps.report@gmx.net>
Date: Mon, 25 Nov 2019 15:59:15 +0100
Subject: [PATCH] tests/meson.build: disable nouveau tests for static build
Signed-off-by: Peter Seiderer <ps.report@gmx.net>
---
Notes:
- the existing test/check for static build in meson.build does not
catch this case because e.g. the buildroot toolchain
br-arm-full-static-2019.05.1 provides an empty libdl.a
169 # Among others FreeBSD does not have a separate dl library.
170 if not cc.has_function('dlsym')
171 dep_dl = cc.find_library('dl', required : with_nouveau)
172 else
173 dep_dl = []
174 endif
---
tests/meson.build | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tests/meson.build b/tests/meson.build
index 6c8ddd9..f7cb5f0 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -44,8 +44,11 @@ endif
if with_etnaviv
subdir('etnaviv')
endif
+lib_type = get_option('default_library')
if with_nouveau
- subdir('nouveau')
+ if lib_type != 'static'
+ subdir('nouveau')
+ endif
endif
drmsl = executable(
--
2.24.0

View file

@ -0,0 +1,212 @@
From 354474609ec628105deec54972bd478bb11403cf Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Thu, 24 Aug 2017 13:28:38 +0100
Subject: [PATCH 2/3] Add sync_fence_info and sync_pt_info
For pre-4.7 kernels, sync_fence_info returns the data from the
SYNC_IOC_FENCE_INFO ioctl. For newer kernels, the SYNC_IOC_FILE_INFO
ioctl is called, and the data converted to SYNC_IOC_FENCE_INFO form.
---
libsync.h | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 172 insertions(+)
diff --git a/libsync.h b/libsync.h
index c3b8a385..44f7330d 100644
--- a/libsync.h
+++ b/libsync.h
@@ -31,6 +31,7 @@
#include <assert.h>
#include <errno.h>
#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
@@ -74,6 +75,54 @@ struct sync_legacy_merge_data {
struct sync_legacy_merge_data)
#endif
+#ifndef SYNC_IOC_FILE_INFO
+/* duplicated from linux/sync_file.h to avoid a build-time dependency
+ * on new (v4.7) kernel headers.
+ */
+struct sync_fence_info {
+ char obj_name[32];
+ char driver_name[32];
+ int32_t status;
+ uint32_t flags;
+ uint64_t timestamp_ns;
+};
+
+struct sync_file_info {
+ char name[32];
+ int32_t status;
+ uint32_t flags;
+ uint32_t num_fences;
+ uint32_t pad;
+ uint64_t sync_fence_info;
+};
+
+#define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info)
+#endif
+
+#ifndef SYNC_IOC_LEGACY_FENCE_INFO
+/* the legacy definitions are based on the contents of
+ * drivers/staging/android/uapi/sync.h in the v4.4 kernel.
+ */
+struct sync_pt_info {
+ uint32_t len;
+ char obj_name[32];
+ char driver_name[32];
+ int32_t status;
+ uint64_t timestamp_ns;
+ uint8_t driver_data[0];
+};
+
+struct sync_fence_info_data {
+ uint32_t len;
+ char name[32];
+ int32_t status;
+ uint8_t pt_info[0];
+};
+
+#define SYNC_IOC_LEGACY_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2, \
+ struct sync_fence_info_data)
+#endif
+
static inline int sync_wait(int fd, int timeout)
{
struct pollfd fds = {0};
@@ -179,6 +228,129 @@ static inline int sync_accumulate(const char *name, int *fd1, int fd2)
return 0;
}
+static inline struct sync_pt_info *sync_pt_info(
+ struct sync_fence_info_data *info,
+ struct sync_pt_info *pt_info)
+{
+ if (!pt_info)
+ pt_info = (struct sync_pt_info *)info->pt_info;
+ else
+ pt_info = (struct sync_pt_info *)((uint8_t *)pt_info +
+ pt_info->len);
+
+ if ((uint32_t)((uint8_t *)pt_info - (uint8_t *)info) >= info->len)
+ return NULL;
+
+ return pt_info;
+}
+
+static inline struct sync_fence_info_data *sync_legacy_fence_info(int fd)
+{
+ const uint32_t len = 4096;
+ struct sync_fence_info_data *info = malloc(len);
+ int ret;
+
+ if (!info)
+ return NULL;
+
+ info->len = len;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ free(info);
+ return NULL;
+ }
+
+ return info;
+}
+
+static inline struct sync_fence_info_data *fence_info_from_file_info(
+ struct sync_file_info *file_info,
+ uint32_t num_fences)
+{
+ struct sync_fence_info_data *info;
+ size_t info_len;
+ struct sync_pt_info *pt_info = NULL;
+ struct sync_fence_info *fence_info;
+ uint32_t i;
+
+ info_len = sizeof(*info) + num_fences * sizeof(*pt_info);
+ info = malloc(info_len);
+ if (!info)
+ return NULL;
+
+ info->len = info_len;
+ strncpy(info->name, file_info->name, sizeof(info->name));
+ info->status = file_info->status;
+
+ fence_info = (struct sync_fence_info *)(uintptr_t)
+ file_info->sync_fence_info;
+ for (i = 0; i < num_fences; i++) {
+ pt_info = sync_pt_info(info, pt_info);
+ assert(pt_info);
+
+ pt_info->len = sizeof(*pt_info);
+ strncpy(pt_info->obj_name, fence_info->obj_name,
+ sizeof(pt_info->obj_name));
+ strncpy(pt_info->driver_name, fence_info->driver_name,
+ sizeof(pt_info->driver_name));
+ pt_info->status = fence_info->status;
+ pt_info->timestamp_ns = fence_info->timestamp_ns;
+
+ fence_info++;
+ }
+
+ return info;
+}
+
+static inline struct sync_fence_info_data *sync_fence_info(int fd)
+{
+ struct sync_fence_info_data *info = NULL;
+ struct sync_file_info initial_info = {""};
+ struct sync_file_info *file_info;
+ int ret;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, &initial_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ if (errno == ENOTTY)
+ return sync_legacy_fence_info(fd);
+ else
+ return NULL;
+ }
+
+ file_info = calloc(1, sizeof(*file_info) + initial_info.num_fences *
+ sizeof(struct sync_fence_info));
+ if (!file_info)
+ return NULL;
+
+ file_info->num_fences = initial_info.num_fences;
+ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1);
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, file_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0)
+ goto free_file_info;
+
+ info = fence_info_from_file_info(file_info, initial_info.num_fences);
+
+free_file_info:
+ free(file_info);
+
+ return info;
+}
+
+static inline void sync_fence_info_free(struct sync_fence_info_data *info)
+{
+ free(info);
+}
#if defined(__cplusplus)
}
#endif
--
2.34.1

View file

@ -0,0 +1,148 @@
From a3188f2de5c1c45d4f9ec0a30ee3d30e4c82d6ea Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Mon, 9 Mar 2020 14:52:17 +0000
Subject: [PATCH 3/3] Add sync_file_info and sync_get_fence_info
For pre-4.7 kernels, sync_file_info calls the SYNC_IOC_FENCE_INFO ioctl,
and converts the data to SYNC_IOC_FILE_INFO form. For newer kernels,
sync_file_info returns data from the SYNC_IOC_FILE_INFO ioctl.
This patch depends on patch "Add sync_fence_info and sync_pt_info",
which added legacy sync info support, using the structure and ioctl
definitions at the top of the patch, as well as the sync_pt_info
function.
---
libsync.h | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/libsync.h b/libsync.h
index 44f7330d..54acb6fa 100644
--- a/libsync.h
+++ b/libsync.h
@@ -351,6 +351,123 @@ static inline void sync_fence_info_free(struct sync_fence_info_data *info)
{
free(info);
}
+
+static inline struct sync_fence_info *sync_get_fence_info(
+ struct sync_file_info *file_info)
+{
+ return (struct sync_fence_info *)(uintptr_t)file_info->sync_fence_info;
+}
+
+static inline struct sync_file_info *file_info_from_info_data(
+ struct sync_fence_info_data *info)
+{
+ struct sync_pt_info *pt_info = NULL;
+ uint32_t num_fences = 0;
+ struct sync_file_info *file_info;
+ struct sync_fence_info *fence_info;
+ uint32_t i;
+
+ while ((pt_info = sync_pt_info(info, pt_info)) != NULL)
+ num_fences++;
+
+ file_info = calloc(1, sizeof(*file_info) + num_fences *
+ sizeof(*fence_info));
+ if (!file_info)
+ return NULL;
+
+ strncpy(file_info->name, info->name, sizeof(file_info->name));
+ file_info->status = info->status;
+ file_info->num_fences = num_fences;
+ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1);
+
+ fence_info = sync_get_fence_info(file_info);
+ for (i = 0; i < num_fences; i++) {
+ pt_info = sync_pt_info(info, pt_info);
+ assert(pt_info);
+
+ strncpy(fence_info->obj_name, pt_info->obj_name,
+ sizeof(fence_info->obj_name));
+ strncpy(fence_info->driver_name, pt_info->driver_name,
+ sizeof(fence_info->driver_name));
+ fence_info->status = pt_info->status;
+ fence_info->timestamp_ns = pt_info->timestamp_ns;
+
+ fence_info++;
+ }
+
+ return file_info;
+}
+
+static inline struct sync_file_info *sync_legacy_file_info(int fd)
+{
+ const uint32_t len = 4096;
+ struct sync_fence_info_data *info = malloc(len);
+ struct sync_file_info *file_info;
+ int ret;
+
+ if (!info)
+ return NULL;
+
+ info->len = len;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ free(info);
+ return NULL;
+ }
+
+ file_info = file_info_from_info_data(info);
+
+ free(info);
+
+ return file_info;
+}
+
+static inline void sync_file_info_free(struct sync_file_info *file_info)
+{
+ free(file_info);
+}
+
+static inline struct sync_file_info *sync_file_info(int fd)
+{
+ struct sync_file_info initial_info = {""};
+ struct sync_file_info *file_info;
+ int ret;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, &initial_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ if (errno == ENOTTY)
+ return sync_legacy_file_info(fd);
+ else
+ return NULL;
+ }
+
+ file_info = calloc(1, sizeof(*file_info) + initial_info.num_fences *
+ sizeof(struct sync_fence_info));
+ if (!file_info)
+ return NULL;
+
+ file_info->num_fences = initial_info.num_fences;
+ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1);
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, file_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ sync_file_info_free(file_info);
+ return NULL;
+ }
+
+ return file_info;
+}
+
#if defined(__cplusplus)
}
#endif
--
2.34.1

View file

@ -1,6 +0,0 @@
# From https://lists.x.org/archives/xorg-announce/2023-February/003323.html
sha256 554cfbfe0542bddb391b4e3e05bfbbfc3e282b955bd56218d21c0616481f65eb libdrm-2.4.115.tar.xz
sha512 0c38d3cfd76f627b899f052527c2939d5fc87a417422dceb0761839ba21e69736703a87ba170b5ba7a4aca2506a240760c8c97ca1781a7fb78468225295293bd libdrm-2.4.115.tar.xz
# Hash for license file
sha256 d0a616a9020dc0271e36e6dd4bad174b4e2c2a42636f13785f8e18dd5f85fd83 data/meson.build

View file

@ -4,7 +4,7 @@
#
################################################################################
LIBDRM_VERSION = 2.4.115
LIBDRM_VERSION = 2.4.110
LIBDRM_SOURCE = libdrm-$(LIBDRM_VERSION).tar.xz
LIBDRM_SITE = https://dri.freedesktop.org/libdrm
LIBDRM_LICENSE = MIT
@ -16,8 +16,8 @@ LIBDRM_DEPENDENCIES = \
host-pkgconf
LIBDRM_CONF_OPTS = \
-Dcairo-tests=disabled \
-Dman-pages=disabled
-Dcairo-tests=false \
-Dman-pages=false
ifeq ($(BR2_PACKAGE_LIBATOMIC_OPS),y)
LIBDRM_DEPENDENCIES += libatomic_ops
@ -27,70 +27,70 @@ endif
endif
ifeq ($(BR2_PACKAGE_LIBDRM_INTEL),y)
LIBDRM_CONF_OPTS += -Dintel=enabled
LIBDRM_CONF_OPTS += -Dintel=true
LIBDRM_DEPENDENCIES += libpciaccess
else
LIBDRM_CONF_OPTS += -Dintel=disabled
LIBDRM_CONF_OPTS += -Dintel=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_RADEON),y)
LIBDRM_CONF_OPTS += -Dradeon=enabled
LIBDRM_CONF_OPTS += -Dradeon=true
else
LIBDRM_CONF_OPTS += -Dradeon=disabled
LIBDRM_CONF_OPTS += -Dradeon=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_AMDGPU),y)
LIBDRM_CONF_OPTS += -Damdgpu=enabled
LIBDRM_CONF_OPTS += -Damdgpu=true
else
LIBDRM_CONF_OPTS += -Damdgpu=disabled
LIBDRM_CONF_OPTS += -Damdgpu=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_NOUVEAU),y)
LIBDRM_CONF_OPTS += -Dnouveau=enabled
LIBDRM_CONF_OPTS += -Dnouveau=true
else
LIBDRM_CONF_OPTS += -Dnouveau=disabled
LIBDRM_CONF_OPTS += -Dnouveau=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_VMWGFX),y)
LIBDRM_CONF_OPTS += -Dvmwgfx=enabled
LIBDRM_CONF_OPTS += -Dvmwgfx=true
else
LIBDRM_CONF_OPTS += -Dvmwgfx=disabled
LIBDRM_CONF_OPTS += -Dvmwgfx=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_OMAP),y)
LIBDRM_CONF_OPTS += -Domap=enabled
LIBDRM_CONF_OPTS += -Domap=true
else
LIBDRM_CONF_OPTS += -Domap=disabled
LIBDRM_CONF_OPTS += -Domap=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_ETNAVIV),y)
LIBDRM_CONF_OPTS += -Detnaviv=enabled
LIBDRM_CONF_OPTS += -Detnaviv=true
else
LIBDRM_CONF_OPTS += -Detnaviv=disabled
LIBDRM_CONF_OPTS += -Detnaviv=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_EXYNOS),y)
LIBDRM_CONF_OPTS += -Dexynos=enabled
LIBDRM_CONF_OPTS += -Dexynos=true
else
LIBDRM_CONF_OPTS += -Dexynos=disabled
LIBDRM_CONF_OPTS += -Dexynos=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_FREEDRENO),y)
LIBDRM_CONF_OPTS += -Dfreedreno=enabled
LIBDRM_CONF_OPTS += -Dfreedreno=true
else
LIBDRM_CONF_OPTS += -Dfreedreno=disabled
LIBDRM_CONF_OPTS += -Dfreedreno=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_TEGRA),y)
LIBDRM_CONF_OPTS += -Dtegra=enabled
LIBDRM_CONF_OPTS += -Dtegra=true
else
LIBDRM_CONF_OPTS += -Dtegra=disabled
LIBDRM_CONF_OPTS += -Dtegra=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_VC4),y)
LIBDRM_CONF_OPTS += -Dvc4=enabled
LIBDRM_CONF_OPTS += -Dvc4=true
else
LIBDRM_CONF_OPTS += -Dvc4=disabled
LIBDRM_CONF_OPTS += -Dvc4=false
endif
ifeq ($(BR2_PACKAGE_HAS_UDEV),y)
@ -101,10 +101,10 @@ LIBDRM_CONF_OPTS += -Dudev=false
endif
ifeq ($(BR2_PACKAGE_VALGRIND),y)
LIBDRM_CONF_OPTS += -Dvalgrind=enabled
LIBDRM_CONF_OPTS += -Dvalgrind=true
LIBDRM_DEPENDENCIES += valgrind
else
LIBDRM_CONF_OPTS += -Dvalgrind=disabled
LIBDRM_CONF_OPTS += -Dvalgrind=false
endif
ifeq ($(BR2_PACKAGE_LIBDRM_INSTALL_TESTS),y)

View file

@ -0,0 +1,232 @@
From e3e0e0f6741cfd44a1b28dff73b394b4afcf04ae Mon Sep 17 00:00:00 2001
From: yanhaodong <haodong.yan@spacemit.com>
Date: Wed, 17 Jan 2024 20:25:02 +0800
Subject: [PATCH] afalg engine support aes-ecb
---
engines/e_afalg.c | 106 +++++++++++++++++++++++++++++++++++++++++-----
engines/e_afalg.h | 12 ++++++
2 files changed, 107 insertions(+), 11 deletions(-)
diff --git a/engines/e_afalg.c b/engines/e_afalg.c
index 14d1d47..18582a8 100644
--- a/engines/e_afalg.c
+++ b/engines/e_afalg.c
@@ -77,7 +77,9 @@ static int afalg_destroy(ENGINE *e);
static int afalg_init(ENGINE *e);
static int afalg_finish(ENGINE *e);
static const EVP_CIPHER *afalg_aes_cbc(int nid);
-static cbc_handles *get_cipher_handle(int nid);
+static const EVP_CIPHER *afalg_aes_ecb(int nid);
+static cbc_handles *cbc_get_cipher_handle(int nid);
+static ecb_handles *ecb_get_cipher_handle(int nid);
static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
const int **nids, int nid);
static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
@@ -95,11 +97,17 @@ static int afalg_cipher_nids[] = {
NID_aes_128_cbc,
NID_aes_192_cbc,
NID_aes_256_cbc,
+ NID_aes_128_ecb,
+ NID_aes_192_ecb,
+ NID_aes_256_ecb,
};
static cbc_handles cbc_handle[] = {{AES_KEY_SIZE_128, NULL},
{AES_KEY_SIZE_192, NULL},
{AES_KEY_SIZE_256, NULL}};
+static ecb_handles ecb_handle[] = {{AES_KEY_SIZE_128, NULL},
+ {AES_KEY_SIZE_192, NULL},
+ {AES_KEY_SIZE_256, NULL}};
static ossl_inline int io_setup(unsigned n, aio_context_t *ctx)
{
@@ -567,6 +575,11 @@ static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
case NID_aes_256_cbc:
ciphername = "cbc(aes)";
break;
+ case NID_aes_128_ecb:
+ case NID_aes_192_ecb:
+ case NID_aes_256_ecb:
+ ciphername = "ecb(aes)";
+ break;
default:
ALG_WARN("%s(%d): Unsupported Cipher type %d\n", __FILE__, __LINE__,
ciphertype);
@@ -686,7 +699,7 @@ static int afalg_cipher_cleanup(EVP_CIPHER_CTX *ctx)
return 1;
}
-static cbc_handles *get_cipher_handle(int nid)
+static cbc_handles *cbc_get_cipher_handle(int nid)
{
switch (nid) {
case NID_aes_128_cbc:
@@ -700,9 +713,23 @@ static cbc_handles *get_cipher_handle(int nid)
}
}
+static ecb_handles *ecb_get_cipher_handle(int nid)
+{
+ switch (nid) {
+ case NID_aes_128_ecb:
+ return &ecb_handle[AES_ECB_128];
+ case NID_aes_192_ecb:
+ return &ecb_handle[AES_ECB_192];
+ case NID_aes_256_ecb:
+ return &ecb_handle[AES_ECB_256];
+ default:
+ return NULL;
+ }
+}
+
static const EVP_CIPHER *afalg_aes_cbc(int nid)
{
- cbc_handles *cipher_handle = get_cipher_handle(nid);
+ cbc_handles *cipher_handle = cbc_get_cipher_handle(nid);
if (cipher_handle->_hidden == NULL
&& ((cipher_handle->_hidden =
EVP_CIPHER_meth_new(nid,
@@ -727,6 +754,33 @@ static const EVP_CIPHER *afalg_aes_cbc(int nid)
return cipher_handle->_hidden;
}
+static const EVP_CIPHER *afalg_aes_ecb(int nid)
+{
+ ecb_handles *cipher_handle = ecb_get_cipher_handle(nid);
+ if (cipher_handle->_hidden == NULL
+ && ((cipher_handle->_hidden =
+ EVP_CIPHER_meth_new(nid,
+ AES_BLOCK_SIZE,
+ cipher_handle->key_size)) == NULL
+ || !EVP_CIPHER_meth_set_iv_length(cipher_handle->_hidden,
+ AES_IV_LEN)
+ || !EVP_CIPHER_meth_set_flags(cipher_handle->_hidden,
+ EVP_CIPH_ECB_MODE |
+ EVP_CIPH_FLAG_DEFAULT_ASN1)
+ || !EVP_CIPHER_meth_set_init(cipher_handle->_hidden,
+ afalg_cipher_init)
+ || !EVP_CIPHER_meth_set_do_cipher(cipher_handle->_hidden,
+ afalg_do_cipher)
+ || !EVP_CIPHER_meth_set_cleanup(cipher_handle->_hidden,
+ afalg_cipher_cleanup)
+ || !EVP_CIPHER_meth_set_impl_ctx_size(cipher_handle->_hidden,
+ sizeof(afalg_ctx)))) {
+ EVP_CIPHER_meth_free(cipher_handle->_hidden);
+ cipher_handle->_hidden= NULL;
+ }
+ return cipher_handle->_hidden;
+}
+
static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
const int **nids, int nid)
{
@@ -743,6 +797,11 @@ static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
case NID_aes_256_cbc:
*cipher = afalg_aes_cbc(nid);
break;
+ case NID_aes_128_ecb:
+ case NID_aes_192_ecb:
+ case NID_aes_256_ecb:
+ *cipher = afalg_aes_ecb(nid);
+ break;
default:
*cipher = NULL;
r = 0;
@@ -771,10 +830,22 @@ static int bind_afalg(ENGINE *e)
* time.
*/
for(i = 0; i < OSSL_NELEM(afalg_cipher_nids); i++) {
- if (afalg_aes_cbc(afalg_cipher_nids[i]) == NULL) {
- AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED);
- return 0;
- }
+ switch (i) {
+ case NID_aes_128_cbc:
+ case NID_aes_192_cbc:
+ case NID_aes_256_cbc:
+ if (afalg_aes_cbc(afalg_cipher_nids[i]) == NULL) {
+ AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED);
+ break;
+ }
+ case NID_aes_128_ecb:
+ case NID_aes_192_ecb:
+ case NID_aes_256_ecb:
+ if (afalg_aes_ecb(afalg_cipher_nids[i]) == NULL) {
+ AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED);
+ break;
+ }
+ }
}
if (!ENGINE_set_ciphers(e, afalg_ciphers)) {
@@ -886,12 +957,24 @@ static int afalg_finish(ENGINE *e)
return 1;
}
-static int free_cbc(void)
+static int free_cipher(void)
{
short unsigned int i;
for(i = 0; i < OSSL_NELEM(afalg_cipher_nids); i++) {
- EVP_CIPHER_meth_free(cbc_handle[i]._hidden);
- cbc_handle[i]._hidden = NULL;
+ switch (i) {
+ case NID_aes_128_cbc:
+ case NID_aes_192_cbc:
+ case NID_aes_256_cbc:
+ EVP_CIPHER_meth_free(cbc_handle[i]._hidden);
+ cbc_handle[i]._hidden = NULL;
+ break;
+ case NID_aes_128_ecb:
+ case NID_aes_192_ecb:
+ case NID_aes_256_ecb:
+ EVP_CIPHER_meth_free(ecb_handle[i]._hidden);
+ ecb_handle[i]._hidden = NULL;
+ break;
+ }
}
return 1;
}
@@ -899,7 +982,8 @@ static int free_cbc(void)
static int afalg_destroy(ENGINE *e)
{
ERR_unload_AFALG_strings();
- free_cbc();
+ free_cipher();
+
return 1;
}
diff --git a/engines/e_afalg.h b/engines/e_afalg.h
index 3323c89..e68d441 100644
--- a/engines/e_afalg.h
+++ b/engines/e_afalg.h
@@ -59,12 +59,24 @@ enum {
AES_CBC_256
};
+enum {
+ AES_ECB_128 = 0,
+ AES_ECB_192,
+ AES_ECB_256
+};
+
struct cbc_cipher_handles {
int key_size;
EVP_CIPHER *_hidden;
};
+struct ecb_cipher_handles {
+ int key_size;
+ EVP_CIPHER *_hidden;
+};
+
typedef struct cbc_cipher_handles cbc_handles;
+typedef struct ecb_cipher_handles ecb_handles;
struct afalg_aio_st {
int efd;
--
2.25.1

View file

@ -82,7 +82,6 @@ define LIBOPENSSL_CONFIGURE_CMDS
no-tests \
no-fuzz-libfuzzer \
no-fuzz-afl \
no-afalgeng \
$(if $(BR2_PACKAGE_LIBOPENSSL_ENABLE_CHACHA),,no-chacha) \
$(if $(BR2_PACKAGE_LIBOPENSSL_ENABLE_RC2),,no-rc2) \
$(if $(BR2_PACKAGE_LIBOPENSSL_ENABLE_RC4),,no-rc4) \

View file

@ -20,7 +20,7 @@ endif
PERF_MAKE_FLAGS = \
$(LINUX_MAKE_FLAGS) \
JOBS=$(PARALLEL_JOBS) \
JOBS=1 \
ARCH=$(PERF_ARCH) \
DESTDIR=$(TARGET_DIR) \
prefix=/usr \

9
package/lmbench/lmbench.mk Normal file → Executable file
View file

@ -40,7 +40,14 @@ define LMBENCH_BUILD_CMDS
endef
define LMBENCH_INSTALL_TARGET_CMDS
$(TARGET_MAKE_ENV) $(MAKE) CFLAGS="$(TARGET_CFLAGS)" OS=$(ARCH) CC="$(TARGET_CC)" BASE=$(TARGET_DIR)/usr -C $(@D)/src install
$(INSTALL) -d $(TARGET_DIR)/usr/bin/lmbench
$(INSTALL) -d $(TARGET_DIR)/usr/bin/lmbench/scripts
$(INSTALL) -d $(TARGET_DIR)/usr/bin/lmbench/bin
cp -rf $(@D)/scripts/* $(TARGET_DIR)/usr/bin/lmbench/scripts
cp -rf $(@D)/bin/* $(TARGET_DIR)/usr/bin/lmbench/bin
rm -f $(TARGET_DIR)/usr/bin/lmbench/bin/*.o
endef
$(eval $(generic-package))

View file

@ -0,0 +1,12 @@
diff --git a/include/lapi/fsmount.h b/include/lapi/fsmount.h
index 07eb42f..1bcc5b4 100644
--- a/include/lapi/fsmount.h
+++ b/include/lapi/fsmount.h
@@ -48,6 +48,7 @@
# define ST_NOSYMFOLLOW 0x2000 /* do not follow symlinks */
#endif
+#define HAVE_STRUCT_MOUNT_ATTR 1
#ifndef HAVE_STRUCT_MOUNT_ATTR
/*
* mount_setattr()

File diff suppressed because it is too large Load diff

View file

@ -1,41 +0,0 @@
From 7b46756a99aca7f27a45c3b99460f088570f6f53 Mon Sep 17 00:00:00 2001
From: Romain Naour <romain.naour@smile.fr>
Date: Wed, 17 Apr 2019 23:07:42 +0200
Subject: [PATCH] meson: Set proper value for LIBCLC_INCLUDEDIR
LIBCLC_INCLUDEDIR is the location where mesa3d OpenCL implementation
will look for OpenCL "headers" on the target, when building the OpenCL
kernels.
The value returned by pkg-config for includedir is relevant when
cross-compiling, on the build machine. But in this specific case, we
really need a value that is valid on the target.
Those headers are installed by the libclc package in /usr/share so
that they are not removed by Buildroot target-finalize logic.
Based on the patch for autotools provided by Valentin Korenblit.
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
[rebased for 20.2.0 & 20.3.0]
---
src/gallium/frontends/clover/meson.build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gallium/frontends/clover/meson.build b/src/gallium/frontends/clover/meson.build
index 62ac5f5278d..ecdeb39669c 100644
--- a/src/gallium/frontends/clover/meson.build
+++ b/src/gallium/frontends/clover/meson.build
@@ -27,7 +27,7 @@
'-DCL_USE_DEPRECATED_OPENCL_2_0_APIS',
'-DCL_USE_DEPRECATED_OPENCL_2_1_APIS',
'-DCL_USE_DEPRECATED_OPENCL_2_2_APIS',
- '-DLIBCLC_INCLUDEDIR="@0@/"'.format(dep_clc.get_variable(pkgconfig : 'includedir')),
+ '-DLIBCLC_INCLUDEDIR="/usr/share"',
'-DLIBCLC_LIBEXECDIR="@0@/"'.format(dep_clc.get_variable(pkgconfig : 'libexecdir'))
]
clover_spirv_cpp_args = []
--
2.20.1

View file

@ -0,0 +1,81 @@
From 42541e6a51d0d7914c5b44486110ce6cffaa9594 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 5 Jun 2014 12:07:01 +0100
Subject: [PATCH 002/168] dri: Add some new DRI formats and fourccs
Add ARGB4444 DRI format and fourcc.
Add YVU444_PACK10_IMG DRI format and fourcc.
Add BGR888 DRI format and fourcc.
---
include/GL/internal/dri_interface.h | 5 +++++
include/drm-uapi/drm_fourcc.h | 1 +
src/egl/drivers/dri2/egl_dri2.c | 1 +
src/gallium/frontends/dri/dri_util.c | 5 +++++
4 files changed, 12 insertions(+)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 7f1f48243e1..8cc16b99f31 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1229,6 +1229,9 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FORMAT_SXRGB8 0x1016
#define __DRI_IMAGE_FORMAT_ABGR16161616 0x1017
#define __DRI_IMAGE_FORMAT_XBGR16161616 0x1018
+#define __DRI_IMAGE_FORMAT_ARGB4444 0x1019
+#define __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG 0x101a
+#define __DRI_IMAGE_FORMAT_BGR888 0x101b
#define __DRI_IMAGE_USE_SHARE 0x0001
#define __DRI_IMAGE_USE_SCANOUT 0x0002
@@ -1260,6 +1263,8 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FOURCC_SARGB8888 0x83324258
#define __DRI_IMAGE_FOURCC_SABGR8888 0x84324258
#define __DRI_IMAGE_FOURCC_SXRGB8888 0x85324258
+#define __DRI_IMAGE_FOURCC_RGBA16161616 0x38344152 /* fourcc_code('R', 'A', '4', '8' ) */
+#define __DRI_IMAGE_FOURCC_SBGR888 0xff324742
/**
* Queryable on images created by createImageFromNames.
diff --git a/include/drm-uapi/drm_fourcc.h b/include/drm-uapi/drm_fourcc.h
index b8f59ae191f..fd84decbd53 100644
--- a/include/drm-uapi/drm_fourcc.h
+++ b/include/drm-uapi/drm_fourcc.h
@@ -383,6 +383,7 @@ extern "C" {
#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
+#define DRM_FORMAT_YVU444_PACK10_IMG fourcc_code('I', 'M', 'G', '2')
/*
* Format Modifiers:
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 8e2767ab311..457255a8ec0 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -2770,6 +2770,7 @@ dri2_num_fourcc_format_planes(EGLint format)
case DRM_FORMAT_Y410:
case DRM_FORMAT_Y412:
case DRM_FORMAT_Y416:
+ case DRM_FORMAT_YVU444_PACK10_IMG:
return 1;
case DRM_FORMAT_NV12:
diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c
index 787e29dcd4f..e8729dac712 100644
--- a/src/gallium/frontends/dri/dri_util.c
+++ b/src/gallium/frontends/dri/dri_util.c
@@ -1072,6 +1072,11 @@ static const struct {
.mesa_format = MESA_FORMAT_B5G5R5A1_UNORM,
.internal_format = GL_RGB5_A1,
},
+ {
+ .image_format = __DRI_IMAGE_FORMAT_ARGB4444,
+ .mesa_format = MESA_FORMAT_B4G4R4A4_UNORM,
+ .internal_format = GL_RGBA4,
+ },
{
.image_format = __DRI_IMAGE_FORMAT_XRGB8888,
.mesa_format = MESA_FORMAT_B8G8R8X8_UNORM,
--
2.17.1

View file

@ -1,84 +0,0 @@
From e3b47c1b84964c62b3e1fa782f1ffa4be0ae62f9 Mon Sep 17 00:00:00 2001
From: Peter Seiderer <ps.report@gmx.net>
Date: Mon, 9 Mar 2020 13:01:14 +0100
Subject: [PATCH] vc4: add meson option to disable optional neon support
Not all toolchains are able to compile the runtime
optional vc4 neon support, so add an meson option
to force disabling it at compile time.
[Upstream: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4114]
Signed-off-by: Peter Seiderer <ps.report@gmx.net>
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
[rebased for 20.2.0, 20.3.0 & 21.1.0]
---
meson_options.txt | 7 +++++++
src/gallium/drivers/vc4/meson.build | 4 ++--
src/gallium/drivers/vc4/vc4_tiling.h | 4 ++--
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/meson_options.txt b/meson_options.txt
index a39596a6f19..0f6b6c62b55 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -123,6 +123,13 @@ option(
choices : ['auto', 'true', 'false', 'enabled', 'disabled'],
description : 'enable gallium va frontend.',
)
+option(
+ 'gallium-vc4-neon',
+ type : 'combo',
+ value : 'auto',
+ choices : ['auto', 'disabled'],
+ description : 'enable gallium vc4 optional neon support.',
+)
option(
'va-libs-path',
type : 'string',
diff --git a/src/gallium/drivers/vc4/meson.build b/src/gallium/drivers/vc4/meson.build
index 5ce5af5f6b4..e3f7d8d62ae 100644
--- a/src/gallium/drivers/vc4/meson.build
+++ b/src/gallium/drivers/vc4/meson.build
@@ -84,7 +84,7 @@ files_libvc4 = files(
vc4_c_args = []
libvc4_neon = []
-if host_machine.cpu_family() == 'arm'
+if host_machine.cpu_family() == 'arm' and get_option('gallium-vc4-neon') != 'disabled'
libvc4_neon = static_library(
'vc4_neon',
'vc4_tiling_lt_neon.c',
@@ -93,7 +93,7 @@ if host_machine.cpu_family() == 'arm'
],
c_args : '-mfpu=neon',
)
- vc4_c_args += '-DUSE_ARM_ASM'
+ vc4_c_args += '-DVC4_TILING_LT_NEON'
endif
if dep_simpenrose.found()
diff --git a/src/gallium/drivers/vc4/vc4_tiling.h b/src/gallium/drivers/vc4/vc4_tiling.h
index 66767e7f1f8..7446f1c3d0c 100644
--- a/src/gallium/drivers/vc4/vc4_tiling.h
+++ b/src/gallium/drivers/vc4/vc4_tiling.h
@@ -89,7 +89,7 @@ vc4_load_lt_image(void *dst, uint32_t dst_stride,
void *src, uint32_t src_stride,
int cpp, const struct pipe_box *box)
{
-#ifdef USE_ARM_ASM
+#ifdef VC4_TILING_LT_NEON
if (util_get_cpu_caps()->has_neon) {
vc4_load_lt_image_neon(dst, dst_stride, src, src_stride,
cpp, box);
@@ -105,7 +105,7 @@ vc4_store_lt_image(void *dst, uint32_t dst_stride,
void *src, uint32_t src_stride,
int cpp, const struct pipe_box *box)
{
-#ifdef USE_ARM_ASM
+#ifdef VC4_TILING_LT_NEON
if (util_get_cpu_caps()->has_neon) {
vc4_store_lt_image_neon(dst, dst_stride, src, src_stride,
cpp, box);
--
2.25.1

View file

@ -0,0 +1,91 @@
From 169d67ed43459bcbc31afe533a795a93f41fe6d4 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 12 Aug 2015 09:11:51 +0100
Subject: [PATCH 003/168] GL_EXT_sparse_texture entry points
---
src/mapi/glapi/gen/EXT_sparse_texture.xml | 44 +++++++++++++++++++++++
src/mapi/glapi/gen/es_EXT.xml | 3 ++
src/mapi/glapi/gen/static_data.py | 1 +
3 files changed, 48 insertions(+)
create mode 100644 src/mapi/glapi/gen/EXT_sparse_texture.xml
diff --git a/src/mapi/glapi/gen/EXT_sparse_texture.xml b/src/mapi/glapi/gen/EXT_sparse_texture.xml
new file mode 100644
index 00000000000..ebeab7d1f9a
--- /dev/null
+++ b/src/mapi/glapi/gen/EXT_sparse_texture.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="EXT_sparse_texture" number="240">
+
+ <enum name="TEXTURE_SPARSE_EXT" value="0x91A6"/>
+ <enum name="VIRTUAL_PAGE_SIZE_INDEX_EXT" value="0x91A7"/>
+
+ <enum name="NUM_SPARSE_LEVELS_EXT" value="0x91AA"/>
+
+ <enum name="NUM_VIRTUAL_PAGE_SIZES_EXT" value="0x91A8"/>
+
+ <enum name="VIRTUAL_PAGE_SIZE_X_EXT" value="0x9195"/>
+ <enum name="VIRTUAL_PAGE_SIZE_Y_EXT" value="0x9196"/>
+ <enum name="VIRTUAL_PAGE_SIZE_Z_EXT" value="0x9197"/>
+
+ <enum name="TEXTURE_2D" value="0x0DE1"/>
+ <enum name="TEXTURE_2D_ARRAY" value="0x8C1A"/>
+ <enum name="TEXTURE_CUBE_MAP" value="0x8513"/>
+ <enum name="TEXTURE_CUBE_MAP_ARRAY_OES" value="0x9009"/>
+ <enum name="TEXTURE_3D" value="0x806F"/>
+
+ <enum name="MAX_SPARSE_TEXTURE_SIZE_EXT" value="0x9198"/>
+ <enum name="MAX_SPARSE_3D_TEXTURE_SIZE_EXT" value="0x9199"/>
+ <enum name="MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT" value="0x919A"/>
+ <enum name="SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT" value="0x91A9"/>
+
+ <function name="TexPageCommitmentEXT" es2="3.1" exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="level" type="GLint"/>
+ <param name="xoffset" type="GLint"/>
+ <param name="yoffset" type="GLint"/>
+ <param name="zoffset" type="GLint"/>
+ <param name="width" type="GLsizei"/>
+ <param name="height" type="GLsizei"/>
+ <param name="depth" type="GLsizei"/>
+ <param name="commit" type="GLboolean"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index e96f5b83f71..79761210760 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1459,6 +1459,9 @@
</category>
+<!-- 240. EXT_sparse_texture -->
+<xi:include href="EXT_sparse_texture.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<category name="GL_OES_viewport_array" number="267">
<function name="ViewportArrayvOES" es2="3.1" alias="ViewportArrayv">
<param name="first" type="GLuint"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index adddef3f3db..ce1e4561139 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1701,6 +1701,7 @@ offsets = {
"DrawElementsUserBuf": 1665,
"MultiDrawArraysUserBuf": 1666,
"MultiDrawElementsUserBuf": 1667,
+ "TexPageCommitmentEXT": 1668,
}
functions = [
--
2.17.1

View file

@ -1,40 +0,0 @@
From fdc8b5a205e2116408aeb9fd305e57f656e2e89d Mon Sep 17 00:00:00 2001
From: Bernd Kuhls <bernd.kuhls@t-online.de>
Date: Sun, 9 Aug 2020 17:06:26 +0200
Subject: [PATCH] src/util/rand_xor: Include stddef.h to fix build error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes
In file included from ../src/util/rand_xor.c:29:
output/host/x86_64-buildroot-linux-uclibc/sysroot/usr/include/sys/random.h:27:35:
error: unknown type name size_t
extern int getrandom(void *__buf, size_t count, unsigned int flags)
seen with gcc version 8.3.0 (Buildroot 2020.02) and uClibc.
Patch sent upstream:
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6248
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
---
src/util/rand_xor.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/util/rand_xor.c b/src/util/rand_xor.c
index 81b64f1ea71..fcb481487fa 100644
--- a/src/util/rand_xor.c
+++ b/src/util/rand_xor.c
@@ -25,6 +25,7 @@
#include "detect_os.h"
#if !DETECT_OS_WINDOWS
+#include <stddef.h>
#if defined(HAVE_GETRANDOM)
#include <sys/random.h>
#endif
--
2.27.0

View file

@ -0,0 +1,106 @@
From 56a75ad069d020aa69d4a3cde3422401b06f1e3a Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 10 Mar 2014 12:27:03 +0000
Subject: [PATCH 004/168] Add support for various GLES extensions
Add support for:
EXT_occlusion_query_boolean
IMG_multisampled_render_to_texture
OES_matrix_palette
---
src/mapi/glapi/gen/es_EXT.xml | 41 ++++++++++++++++++++++++-------
src/mapi/glapi/gen/static_data.py | 6 +++++
2 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index 79761210760..03c78ef9ca5 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -285,28 +285,25 @@
<enum name="WEIGHT_ARRAY_BUFFER_BINDING_OES" value="0x889E"/>
<enum name="MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES" value="0x8B9E"/>
- <function name="CurrentPaletteMatrixOES" alias="CurrentPaletteMatrixARB"
- exec="skip">
+ <function name="CurrentPaletteMatrixOES" es1="1.0" exec="dynamic">
<param name="matrixpaletteindex" type="GLuint"/>
</function>
- <!-- no offset -->
- <function name="LoadPaletteFromModelViewMatrixOES" exec="skip">
+ <function name="LoadPaletteFromModelViewMatrixOES" es1="1.0" exec="dynamic">
</function>
- <function name="MatrixIndexPointerOES" alias="MatrixIndexPointerARB"
- exec="skip">
+ <function name="MatrixIndexPointerOES" es1="1.0" exec="dynamic">
<param name="size" type="GLint"/>
<param name="type" type="GLenum"/>
<param name="stride" type="GLsizei"/>
- <param name="pointer" type="const GLvoid *"/>
+ <param name="pointer" type="GLvoid *"/>
</function>
- <function name="WeightPointerOES" alias="WeightPointerARB" exec="skip">
+ <function name="WeightPointerOES" es1="1.0" exec="dynamic">
<param name="size" type="GLint"/>
<param name="type" type="GLenum"/>
<param name="stride" type="GLsizei"/>
- <param name="pointer" type="const GLvoid *"/>
+ <param name="pointer" type="GLvoid *"/>
</function>
</category>
@@ -680,6 +677,32 @@
</enum>
</category>
+<!-- 74. GL_IMG_multisampled_render_to_texture -->
+<category name="GL_IMG_multisampled_render_to_texture" number="74">
+ <enum name="RENDERBUFFER_SAMPLES_IMG" value="0x9133"/>
+ <enum name="FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG" value="0x9134"/>
+ <enum name="MAX_SAMPLES_IMG" value="0x9135"/>
+ <enum name="TEXTURE_SAMPLES_IMG" value="0x9136"/>
+
+ <function name="RenderbufferStorageMultisampleIMG" es2="2.0" exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="samples" type="GLsizei"/>
+ <param name="internalformat" type="GLenum"/>
+ <param name="width" type="GLsizei"/>
+ <param name="height" type="GLsizei"/>
+ </function>
+
+ <function name="FramebufferTexture2DMultisampleIMG" es2="2.0"
+ exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="textarget" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="samples" type="GLsizei"/>
+ </function>
+</category>
+
<!-- 87. GL_OES_EGL_image_external -->
<category name="GL_OES_EGL_image_external" number="87">
<enum name="TEXTURE_EXTERNAL_OES" value="0x8D65"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index ce1e4561139..c815f13d116 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1702,6 +1702,12 @@ offsets = {
"MultiDrawArraysUserBuf": 1666,
"MultiDrawElementsUserBuf": 1667,
"TexPageCommitmentEXT": 1668,
+ "CurrentPaletteMatrixOES" : 1669,
+ "LoadPaletteFromModelViewMatrixOES" : 1670,
+ "MatrixIndexPointerOES" : 1671,
+ "WeightPointerOES" : 1672,
+ "RenderbufferStorageMultisampleIMG" : 1673,
+ "FramebufferTexture2DMultisampleIMG" : 1674,
}
functions = [
--
2.17.1

View file

@ -1,70 +0,0 @@
From 09ce52fe375a6fc1ccf51b6b691aaa2c3f53fbd5 Mon Sep 17 00:00:00 2001
From: Bernd Kuhls <bernd.kuhls@t-online.de>
Date: Fri, 3 Jun 2022 16:26:03 +0200
Subject: [PATCH] Fix uClibc build
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes build errors with uClibc and gcc-9.3.0:
../src/gallium/drivers/lima/lima_texture.c:47:15: error: expected
declaration specifiers or ... before __builtin_offsetof
47 | static_assert(offsetof(lima_tex_desc, va) == 24,
"lima_tex_desc->va offset isn't 24");
../src/egl/main/egldisplay.c: In function _eglGetNativePlatformFromEnv:
../src/egl/main/egldisplay.c:101:4: error: implicit declaration of
function static_assert [-Werror=implicit-function-declaration] 101 |
static_assert(ARRAY_SIZE(egl_platforms) == _EGL_NUM_PLATFORMS,
../src/util/macros.h:74:4: error: implicit declaration of function
static_assert [-Werror=implicit-function-declaration]
74 | static_assert(cond, #cond); \
| ^~~~~~~~~~~~~
Patch sent upstream:
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13898
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
---
src/util/compiler.h | 10 ++++++++++
src/util/macros.h | 1 +
2 files changed, 11 insertions(+)
diff --git a/src/util/compiler.h b/src/util/compiler.h
index d184ad455af..b5c56807acc 100644
--- a/src/util/compiler.h
+++ b/src/util/compiler.h
@@ -36,6 +36,16 @@
#include <assert.h>
+/*
+ * C11 static_assert() macro
+ * assert.h only defines that name for C11 and above
+ */
+#if !defined(__cplusplus)
+#ifndef static_assert
+#define static_assert _Static_assert
+#endif
+#endif
+
#include "util/macros.h"
diff --git a/src/util/macros.h b/src/util/macros.h
index 22b18303826..8f73ee72693 100644
--- a/src/util/macros.h
+++ b/src/util/macros.h
@@ -27,6 +27,7 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
+#include "util/compiler.h"
/* Compute the size of an array */
#ifndef ARRAY_SIZE
--
2.34.1

View file

@ -0,0 +1,178 @@
From bc7244906f23b0ea66835c7dde2523598659051c Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 11 Mar 2014 11:50:53 +0000
Subject: [PATCH 005/168] Add EGL_IMG_cl_image extension
Add support for the experimental EGL_IMG_cl_image extension to EGL, and
the DRI2 EGL driver.
---
include/EGL/eglmesaext.h | 5 +++
include/GL/internal/dri_interface.h | 13 +++++++
src/egl/drivers/dri2/egl_dri2.c | 58 +++++++++++++++++++++++++----
src/egl/main/eglapi.c | 1 +
src/egl/main/egldisplay.h | 2 +
5 files changed, 72 insertions(+), 7 deletions(-)
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index f0395a8a58c..5d11f3e488e 100644
--- a/include/EGL/eglmesaext.h
+++ b/include/EGL/eglmesaext.h
@@ -49,6 +49,11 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
#define EGL_DRM_BUFFER_FORMAT_RGB565_MESA 0x3292
#endif /* EGL_MESA_drm_image_formats */
+#ifndef EGL_IMG_cl_image
+#define EGL_IMG_cl_image 1
+#define EGL_CL_IMAGE_IMG 0x6010
+#endif /* Experimental eglCreateImageKHR target */
+
#ifdef __cplusplus
}
#endif
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 8cc16b99f31..9f7d805825f 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1723,6 +1723,19 @@ struct __DRIimageExtensionRec {
* \since 21
*/
void (*setInFenceFd)(__DRIimage *image, int fd);
+
+ /**
+ * Support for experimental EGL_CL_IMAGE_IMG.
+ * Like createImageFromTexture, but from a buffer, the contents
+ * of which depend on the target.
+ *
+ * \since 8
+ */
+ __DRIimage *(*createImageFromBuffer)(__DRIcontext *context,
+ int target,
+ void *buffer,
+ unsigned *error,
+ void *loaderPrivate);
};
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 457255a8ec0..5ed9898993b 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1024,6 +1024,10 @@ dri2_setup_screen(_EGLDisplay *disp)
disp->Extensions.EXT_image_dma_buf_import_modifiers = EGL_TRUE;
}
#endif
+ if (dri2_dpy->image->base.version >= 8 &&
+ dri2_dpy->image->createImageFromBuffer) {
+ disp->Extensions.IMG_cl_image = EGL_TRUE;
+ }
}
if (dri2_dpy->flush_control)
@@ -2465,17 +2469,13 @@ dri2_get_msc_rate_angle(_EGLDisplay *disp, _EGLSurface *surf,
return dri2_dpy->vtbl->get_msc_rate(disp, surf, numerator, denominator);
}
-/**
- * Set the error code after a call to
- * dri2_egl_image::dri_image::createImageFromTexture.
- */
static void
-dri2_create_image_khr_texture_error(int dri_error)
+dri2_create_image_khr_error(int dri_error)
{
EGLint egl_error = egl_error_from_dri_image_error(dri_error);
if (egl_error != EGL_SUCCESS)
- _eglError(egl_error, "dri2_create_image_khr_texture");
+ _eglError(egl_error, "dri2_create_image_khr");
}
static _EGLImage *
@@ -2554,7 +2554,49 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
attrs.GLTextureLevel,
&error,
NULL);
- dri2_create_image_khr_texture_error(error);
+ dri2_create_image_khr_error(error);
+
+ if (!dri2_img->dri_image) {
+ free(dri2_img);
+ return EGL_NO_IMAGE_KHR;
+ }
+ return &dri2_img->base;
+}
+
+static _EGLImage *
+dri2_create_image_img_buffer(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint *attr_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+ struct dri2_egl_image *dri2_img;
+ unsigned error;
+
+ switch (target) {
+ case EGL_CL_IMAGE_IMG:
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ dri2_img = malloc(sizeof *dri2_img);
+ if (!dri2_img) {
+ _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ _eglInitImage(&dri2_img->base, disp);
+
+ dri2_img->dri_image =
+ dri2_dpy->image->createImageFromBuffer(dri2_ctx->dri_context,
+ target,
+ buffer,
+ &error,
+ NULL);
+ dri2_create_image_khr_error(error);
if (!dri2_img->dri_image) {
free(dri2_img);
@@ -3300,6 +3342,8 @@ dri2_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target,
case EGL_WAYLAND_BUFFER_WL:
return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
#endif
+ case EGL_CL_IMAGE_IMG:
+ return dri2_create_image_img_buffer(disp, ctx, target, buffer, attr_list);
default:
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
return EGL_NO_IMAGE_KHR;
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 041f35aa7b6..002c94aac2c 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -613,6 +613,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(WL_bind_wayland_display);
_EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
+ _EGL_CHECK_EXTENSION(IMG_cl_image);
#undef _EGL_CHECK_EXTENSION
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 28c2b299608..b4b2a2fe22b 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -157,6 +157,8 @@ struct _egl_extensions
EGLBoolean WL_bind_wayland_display;
EGLBoolean WL_create_wayland_buffer_from_image;
+
+ EGLBoolean IMG_cl_image;
};
struct _egl_display
--
2.17.1

View file

@ -0,0 +1,48 @@
From 11641a07afb125f69f376f43dcd51352bd0b731b Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 15 Sep 2015 14:15:31 +0100
Subject: [PATCH 006/168] egl: optimise eglMakeCurrent for the case where
nothing has changed
When an application calls eglMakeCurrent with a context, draw surface and
read surface that match those that are currently bound to the calling
thread don't perform a flush as this is an expensive operation.
---
src/egl/main/eglapi.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 002c94aac2c..5e69f1cb856 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -935,6 +935,7 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
EGLContext ctx)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLContext *current_context = _eglGetCurrentContext();
_EGLContext *context = _eglLookupContext(ctx, disp);
_EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
_EGLSurface *read_surf = _eglLookupSurface(read, disp);
@@ -988,8 +989,17 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
draw_surf && !draw_surf->ProtectedContent)
RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
- egl_relax (disp, &draw_surf->Resource, &read_surf->Resource, &context->Resource) {
- ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context);
+ /* As an optimisation don't do anything unless something has changed */
+ if (context != current_context ||
+ (current_context &&
+ (draw_surf != current_context->DrawSurface ||
+ read_surf != current_context->ReadSurface)) ||
+ (!current_context && (draw_surf || read_surf))) {
+ egl_relax (disp, &draw_surf->Resource, &read_surf->Resource, &context->Resource) {
+ ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context);
+ }
+ } else {
+ ret = EGL_TRUE;
}
RETURN_EGL_EVAL(disp, ret);
--
2.17.1

View file

@ -0,0 +1,84 @@
From a47e58027d672fe1a3e1b1d11113b799322e7344 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 4 Feb 2016 14:09:26 +0000
Subject: [PATCH 007/168] GL_EXT_shader_pixel_local_storage2 entry points
---
.../gen/EXT_shader_pixel_local_storage2.xml | 35 +++++++++++++++++++
src/mapi/glapi/gen/es_EXT.xml | 3 ++
src/mapi/glapi/gen/static_data.py | 3 ++
3 files changed, 41 insertions(+)
create mode 100644 src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml
diff --git a/src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml b/src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml
new file mode 100644
index 00000000000..20e186c0f0d
--- /dev/null
+++ b/src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="EXT_shader_pixel_local_storage2" number="240">
+
+ <enum name="GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT" value="0x8F63"/>
+ <enum name="GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT" value="0x8F67"/>
+ <enum name="GL_SHADER_PIXEL_LOCAL_STORAGE_EXT" value="0x8F64"/>
+ <enum name="GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT" value="0x9650"/>
+ <enum name="GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT" value="0x9651"/>
+ <enum name="GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT" value="0x9652"/>
+
+ <function name="ClearPixelLocalStorageuiEXT" es2="3.1" exec="dynamic">
+ <param name="offset" type="GLsizei"/>
+ <param name="n" type="GLsizei"/>
+ <param name="values" type="const GLuint *"/>
+ </function>
+
+ <function name="FramebufferPixelLocalStorageSizeEXT" es2="3.1"
+ exec="dynamic">
+ <param name="target" type="GLuint"/>
+ <param name="size" type="GLsizei"/>
+ </function>
+
+ <function name="GetFramebufferPixelLocalStorageSizeEXT" es2="3.1"
+ exec="dynamic">
+ <param name="target" type="GLuint"/>
+ <return type="GLsizei"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index 03c78ef9ca5..0ed0e003bae 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1485,6 +1485,9 @@
<!-- 240. EXT_sparse_texture -->
<xi:include href="EXT_sparse_texture.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<!-- 253. GL_EXT_shader_pixel_local_storage2 -->
+<xi:include href="EXT_shader_pixel_local_storage2.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<category name="GL_OES_viewport_array" number="267">
<function name="ViewportArrayvOES" es2="3.1" alias="ViewportArrayv">
<param name="first" type="GLuint"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index c815f13d116..45780fb35f0 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1708,6 +1708,9 @@ offsets = {
"WeightPointerOES" : 1672,
"RenderbufferStorageMultisampleIMG" : 1673,
"FramebufferTexture2DMultisampleIMG" : 1674,
+ "ClearPixelLocalStorageuiEXT" : 1675,
+ "FramebufferPixelLocalStorageSizeEXT" : 1676,
+ "GetFramebufferPixelLocalStorageSizeEXT" : 1677,
}
functions = [
--
2.17.1

View file

@ -0,0 +1,85 @@
From 9cbd33f64209a30f7b27d996c550af2d36d9bd1d Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 4 Feb 2016 14:09:26 +0000
Subject: [PATCH 008/168] GL_IMG_framebuffer_downsample entry points
---
.../glapi/gen/IMG_framebuffer_downsample.xml | 37 +++++++++++++++++++
src/mapi/glapi/gen/es_EXT.xml | 3 ++
src/mapi/glapi/gen/static_data.py | 2 +
3 files changed, 42 insertions(+)
create mode 100644 src/mapi/glapi/gen/IMG_framebuffer_downsample.xml
diff --git a/src/mapi/glapi/gen/IMG_framebuffer_downsample.xml b/src/mapi/glapi/gen/IMG_framebuffer_downsample.xml
new file mode 100644
index 00000000000..b5ce77dfb08
--- /dev/null
+++ b/src/mapi/glapi/gen/IMG_framebuffer_downsample.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_IMG_framebuffer_downsample" number="255">
+
+ <enum name="FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG" value="0x913C"/>
+ <enum name="NUM_DOWNSAMPLE_SCALES_IMG" value="0x913D"/>
+ <enum name="DOWNSAMPLE_SCALES_IMG" value="0x913E"/>
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG" value="0x913F"/>
+
+ <function name="FramebufferTexture2DDownsampleIMG" es1="1.0" es2="2.0"
+ exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="textarget" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="xscale" type="GLint"/>
+ <param name="yscale" type="GLint"/>
+ </function>
+
+ <function name="FramebufferTextureLayerDownsampleIMG" es1="1.0" es2="2.0"
+ exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="layer" type="GLint"/>
+ <param name="xscale" type="GLint"/>
+ <param name="yscale" type="GLint"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index 0ed0e003bae..94696d535b9 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1488,6 +1488,9 @@
<!-- 253. GL_EXT_shader_pixel_local_storage2 -->
<xi:include href="EXT_shader_pixel_local_storage2.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<!-- 255. GL_IMG_framebuffer_downsample -->
+<xi:include href="IMG_framebuffer_downsample.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<category name="GL_OES_viewport_array" number="267">
<function name="ViewportArrayvOES" es2="3.1" alias="ViewportArrayv">
<param name="first" type="GLuint"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 45780fb35f0..460064e1769 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1711,6 +1711,8 @@ offsets = {
"ClearPixelLocalStorageuiEXT" : 1675,
"FramebufferPixelLocalStorageSizeEXT" : 1676,
"GetFramebufferPixelLocalStorageSizeEXT" : 1677,
+ "FramebufferTexture2DDownsampleIMG" : 1678,
+ "FramebufferTextureLayerDownsampleIMG" : 1679,
}
functions = [
--
2.17.1

View file

@ -0,0 +1,53 @@
From 3ed890874b9d2ccb163ee94c705b18375c8e0cc6 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 11 Jul 2016 12:45:30 +0100
Subject: [PATCH 009/168] GL_OVR_multiview entry points
---
src/mapi/glapi/gen/gl_API.xml | 17 +++++++++++++++++
src/mapi/glapi/gen/static_data.py | 1 +
2 files changed, 18 insertions(+)
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 8ead49dbc3d..2526770fe35 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -12683,6 +12683,23 @@
</function>
</category>
+<category name="GL_OVR_multiview" number="478">
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR" value="0x9630" />
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR" value="0x9632" />
+ <enum name="MAX_VIEWS_OVR" value="0x9631">
+ <size name="Get" mode="get"/>
+ </enum>
+ <enum name="FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR" value="0x9633" />
+ <function name="FramebufferTextureMultiviewOVR" es2="3.0" exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="baseViewIndex" type="GLint"/>
+ <param name="numViews" type="GLsizei"/>
+ </function>
+</category>
+
<xi:include href="EXT_window_rectangles.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<!-- 520. GL_EXT_shader_framebuffer_fetch -->
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 460064e1769..3337856b3b6 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1713,6 +1713,7 @@ offsets = {
"GetFramebufferPixelLocalStorageSizeEXT" : 1677,
"FramebufferTexture2DDownsampleIMG" : 1678,
"FramebufferTextureLayerDownsampleIMG" : 1679,
+ "FramebufferTextureMultiviewOVR" : 1680,
}
functions = [
--
2.17.1

View file

@ -0,0 +1,68 @@
From 7797b0fb638351ae1ad5484baa43ce2dd212871b Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 11 Jul 2016 13:29:51 +0100
Subject: [PATCH 010/168] Add OVR_multiview_multisampled_render_to_texture
---
...ltiview_multisampled_render_to_texture.xml | 21 +++++++++++++++++++
src/mapi/glapi/gen/es_EXT.xml | 3 +++
src/mapi/glapi/gen/static_data.py | 1 +
3 files changed, 25 insertions(+)
create mode 100644 src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml
diff --git a/src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml b/src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml
new file mode 100644
index 00000000000..86bebc728e9
--- /dev/null
+++ b/src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_OVR_multiview_multisampled_render_to_texture" number="250">
+
+ <function name="FramebufferTextureMultisampleMultiviewOVR" es2="3.0"
+ exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="samples" type="GLsizei"/>
+ <param name="baseViewIndex" type="GLint"/>
+ <param name="numViews" type="GLsizei"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index 94696d535b9..b59e85d3281 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1485,6 +1485,9 @@
<!-- 240. EXT_sparse_texture -->
<xi:include href="EXT_sparse_texture.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<!-- 250. GL_OVR_multiview_multisampled_render_to_texture -->
+<xi:include href="OVR_multiview_multisampled_render_to_texture.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<!-- 253. GL_EXT_shader_pixel_local_storage2 -->
<xi:include href="EXT_shader_pixel_local_storage2.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 3337856b3b6..2255385128c 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1714,6 +1714,7 @@ offsets = {
"FramebufferTexture2DDownsampleIMG" : 1678,
"FramebufferTextureLayerDownsampleIMG" : 1679,
"FramebufferTextureMultiviewOVR" : 1680,
+ "FramebufferTextureMultisampleMultiviewOVR" : 1681,
}
functions = [
--
2.17.1

View file

@ -0,0 +1,57 @@
From 191fd54bcb96ec12be4107737345695bc6f662ac Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 18 Aug 2016 15:52:28 +0100
Subject: [PATCH 011/168] wayland-drm: install wayland-drm.xml to the
configured pkgdatadir
Add a pkg-config file as well so that it can be located without hardcoding the
path.
---
src/egl/wayland/wayland-drm/meson.build | 15 +++++++++++++++
src/egl/wayland/wayland-drm/wayland-drm.pc.in | 7 +++++++
2 files changed, 22 insertions(+)
create mode 100644 src/egl/wayland/wayland-drm/wayland-drm.pc.in
diff --git a/src/egl/wayland/wayland-drm/meson.build b/src/egl/wayland/wayland-drm/meson.build
index b4782a013c9..f291ef9f55e 100644
--- a/src/egl/wayland/wayland-drm/meson.build
+++ b/src/egl/wayland/wayland-drm/meson.build
@@ -49,6 +49,21 @@ libwayland_drm = static_library(
build_by_default : false,
)
+install_data('wayland-drm.xml')
+
+pkg.generate(
+ filebase : 'wayland-drm',
+ name : 'Mesa Wayland Protocols',
+ description : 'Mesa Wayland protocol files',
+ version : meson.project_version(),
+ variables : [
+ 'datarootdir=${prefix}/' + get_option('datadir'),
+ 'pkgdatadir=${pc_sysrootdir}${datarootdir}/' + meson.project_name(),
+ ],
+ install_dir : '@0@/@1@/pkgconfig'.format(get_option('prefix'),
+ get_option('datadir')),
+)
+
# linux-dmabuf isn't part of wayland-drm, but this happens to be the only
# place which is a) guaranteed to be built when building either or both
# of EGL and Vulkan WSI, and b) guaranteed to be included before both,
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.pc.in b/src/egl/wayland/wayland-drm/wayland-drm.pc.in
new file mode 100644
index 00000000000..d08ccdaf6ce
--- /dev/null
+++ b/src/egl/wayland/wayland-drm/wayland-drm.pc.in
@@ -0,0 +1,7 @@
+prefix=@prefix@
+datarootdir=@datarootdir@
+pkgdatadir=${pc_sysrootdir}@datadir@/@PACKAGE@
+
+Name: @PACKAGE_NAME@ Wayland Protocols
+Description: @PACKAGE_NAME@ Wayland protocol files
+Version: @PACKAGE_VERSION@
\ No newline at end of file
--
2.17.1

View file

@ -0,0 +1,27 @@
From 7411e88f1ddbe42864614954887d0aca0f0bbce0 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 26 Oct 2016 16:24:28 +0100
Subject: [PATCH 012/168] Enable buffer sharing in the kms_swrast driver
Enable buffer sharing, so that a DRI driver can be loaded by a
Wayland client when kms_swrast is being used by the compositor.
---
src/gallium/frontends/dri/dri2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c
index 2dbb6a97070..eca2986eeb9 100644
--- a/src/gallium/frontends/dri/dri2.c
+++ b/src/gallium/frontends/dri/dri2.c
@@ -2344,7 +2344,7 @@ dri_swrast_kms_init_screen(__DRIscreen * sPriv)
if (!configs)
goto destroy_screen;
- screen->can_share_buffer = false;
+ screen->can_share_buffer = true;
screen->auto_fake_front = dri_with_format(sPriv);
screen->lookup_egl_image = dri2_lookup_egl_image;
--
2.17.1

View file

@ -0,0 +1,46 @@
From be55dbacf71a760ef10930355295ba1ce21af8ff Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 28 Feb 2017 16:08:47 +0000
Subject: [PATCH 013/168] egl/wayland: add support for RGB565 back buffers
---
src/egl/drivers/dri2/platform_wayland.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 93bb97c54e0..850a197d952 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -1096,18 +1096,27 @@ back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
__DRIimage *image;
- int name, pitch;
+ int name, pitch, format;
image = dri2_surf->back->dri_image;
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
+ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
buffer->attachment = __DRI_BUFFER_BACK_LEFT;
buffer->name = name;
buffer->pitch = pitch;
- buffer->cpp = 4;
buffer->flags = 0;
+
+ switch (format) {
+ case __DRI_IMAGE_FORMAT_RGB565:
+ buffer->cpp = 2;
+ break;
+ default:
+ buffer->cpp = 4;
+ break;
+ }
}
/* Value chosen empirically as a compromise between avoiding frequent
--
2.17.1

View file

@ -0,0 +1,33 @@
From 3d5b7866ca7900e3361ef33467c2f6ebb6834344 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 8 Nov 2017 15:15:20 +0000
Subject: [PATCH 014/168] egl/wayland: post maximum damage when blitting
When blitting, as part of the "is_different_gpu" case when swapping
buffers, the blit is done using the full surface dimensions, ignoring
the damage region. This results in corruption of the non damaged region
on screen. Workaround this by posting maximum damage when blitting.
A better fix would be to limit the blit to the damaged region, at least
when the number of damage rectangles is 1.
---
src/egl/drivers/dri2/platform_wayland.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 850a197d952..73a443b4b40 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -1593,7 +1593,8 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
/* If the compositor doesn't support damage_buffer, we deliberately
* ignore the damage region and post maximum damage, due to
* https://bugs.freedesktop.org/78190 */
- if (!n_rects || !try_damage_buffer(dri2_surf, rects, n_rects))
+ if (dri2_dpy->is_different_gpu ||
+ !n_rects || !try_damage_buffer(dri2_surf, rects, n_rects))
wl_surface_damage(dri2_surf->wl_surface_wrapper,
0, 0, INT32_MAX, INT32_MAX);
--
2.17.1

View file

@ -0,0 +1,34 @@
From 8390d311042bb9b54e6d39193a00276f34a6ad8a Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 8 Nov 2017 15:26:25 +0000
Subject: [PATCH 015/168] egl/wayland: flush the drawable before blitting
Flush the drawable before blitting in the "is_different_gpu" case when
swapping buffers, and pass the flush flag to the blitImage call. The
change brings the code into line with the way the DRI3 GLX code works.
For the PowerVR driver, the drawable parameters that will be used in
the flush have been obtained previously, including any native fence
associated with the blit source. The blit will result in a new native
fence for the source, and make the one in the drawable parameters
invalid.
---
src/egl/drivers/dri2/platform_wayland.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 73a443b4b40..8f1c5101441 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -1607,7 +1607,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
0, 0, dri2_surf->base.Width,
dri2_surf->base.Height,
0, 0, dri2_surf->base.Width,
- dri2_surf->base.Height, 0);
+ dri2_surf->base.Height, __BLIT_FLAG_FLUSH);
}
wl_surface_commit(dri2_surf->wl_surface_wrapper);
--
2.17.1

View file

@ -0,0 +1,54 @@
From b788d8ee10adf01acd6d139ea7f73ab6f58fcc45 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 23 Nov 2017 15:50:21 +0000
Subject: [PATCH 016/168] dri: use a supported API in driCreateNewContext
Don't assume the screen supports OpenGL when creating a new context,
use an API that the screen supports.
---
src/gallium/frontends/dri/dri_util.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c
index e8729dac712..6c3ce760ab0 100644
--- a/src/gallium/frontends/dri/dri_util.c
+++ b/src/gallium/frontends/dri/dri_util.c
@@ -48,6 +48,7 @@
#include "main/version.h"
#include "main/debug_output.h"
#include "main/errors.h"
+#include "util/bitscan.h"
driOptionDescription __dri2ConfigOptions[] = {
DRI_CONF_SECTION_DEBUG
@@ -489,7 +490,11 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
mesa_api = API_OPENGLES;
break;
case __DRI_API_GLES2:
+ ctx_config.major_version = 2;
+ mesa_api = API_OPENGLES2;
+ break;
case __DRI_API_GLES3:
+ ctx_config.major_version = 3;
mesa_api = API_OPENGLES2;
break;
case __DRI_API_OPENGL_CORE:
@@ -675,7 +680,14 @@ static __DRIcontext *
driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
__DRIcontext *shared, void *data)
{
- return driCreateNewContextForAPI(screen, __DRI_API_OPENGL,
+ int apifs;
+
+ apifs = ffs(screen->api_mask);
+
+ if (!apifs)
+ return NULL;
+
+ return driCreateNewContextForAPI(screen, apifs - 1,
config, shared, data);
}
--
2.17.1

View file

@ -0,0 +1,215 @@
From 4e73467f49320e7647ec8e95a754f7574733838f Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 28 Nov 2017 16:27:38 +0000
Subject: [PATCH 017/168] gbm: add gbm_bo_blit
For the GBM DRI backend, gbm_bo_blit is a wrapper around blitImage in
the DRI Image extension.
---
src/gbm/backends/dri/gbm_dri.c | 33 +++++++++++++++++++++++++++++++++
src/gbm/main/gbm.c | 31 +++++++++++++++++++++++++++++++
src/gbm/main/gbm.h | 21 +++++++++++++++++++++
src/gbm/main/gbm_abi_check.c | 20 +++++++++++++++++++-
src/gbm/main/gbm_backend_abi.h | 8 ++++++++
5 files changed, 112 insertions(+), 1 deletion(-)
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index 36cee87a2fd..6dad8d97d17 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -1412,6 +1412,37 @@ gbm_dri_surface_destroy(struct gbm_surface *_surf)
free(surf);
}
+static int
+gbm_dri_bo_blit(struct gbm_bo *_dst_bo, struct gbm_bo *_src_bo,
+ int dst_x0, int dst_y0, int dst_width, int dst_height,
+ int src_x0, int src_y0, int src_width, int src_height,
+ enum gbm_blit_flags flags)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(_dst_bo->gbm);
+ struct gbm_dri_bo *dst_bo = gbm_dri_bo(_dst_bo);
+ struct gbm_dri_bo *src_bo = gbm_dri_bo(_src_bo);
+
+ if (!dri->image || dri->image->base.version < 9 || !dri->image->blitImage) {
+ errno = ENOSYS;
+ return 0;
+ }
+
+ mtx_lock(&dri->mutex);
+ if (!dri->context)
+ dri->context = dri->dri2->createNewContext(dri->screen, NULL,
+ NULL, NULL);
+ assert(dri->context);
+ mtx_unlock(&dri->mutex);
+
+ /* GBM flags and DRI flags are the same, so just pass them on */
+ dri->image->blitImage(dri->context, dst_bo->image, src_bo->image,
+ dst_x0, dst_y0, dst_width, dst_height,
+ src_x0, src_y0, src_width, src_height,
+ flags);
+
+ return 1;
+}
+
static void
dri_destroy(struct gbm_device *gbm)
{
@@ -1473,6 +1504,8 @@ dri_device_create(int fd, uint32_t gbm_backend_version)
dri->base.v0.name = "drm";
+ dri->base.v1.bo_blit = gbm_dri_bo_blit;
+
dri->visual_table = gbm_dri_visuals_table;
dri->num_visuals = ARRAY_SIZE(gbm_dri_visuals_table);
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
index 599f7aae9b6..27e9f5bcd03 100644
--- a/src/gbm/main/gbm.c
+++ b/src/gbm/main/gbm.c
@@ -827,6 +827,37 @@ gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc)
return desc->name;
}
+/**
+ * Blit from one buffer object to another
+ *
+ * \param dst_bo The destination buffer object
+ * \param src_bo The source buffer object
+ * \param dst_x0 The X coordinate (top left origin) of the destination rectangle
+ * \param dst_y0 The Y coordinate (top left origin) of the destination rectangle
+ * \param dst_width The width of the destination rectangle
+ * \param dst_height The height of the destination rectangle
+ * \param src_x0 The X coordinate (top left origin) of the source rectangle
+ * \param src_y0 The Y coordinate (top left origin) of the source rectangle
+ * \param src_width The width of the source rectangle
+ * \param src_height The height of the source rectangle
+ * \param flags The flags for the blit
+ * \return 1 on success, 0 otherwise
+ */
+GBM_EXPORT int
+gbm_bo_blit(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
+ int dst_x0, int dst_y0, int dst_width, int dst_height,
+ int src_x0, int src_y0, int src_width, int src_height,
+ enum gbm_blit_flags flags)
+{
+ if (dst_bo->gbm->v0.backend_version >= 1)
+ return dst_bo->gbm->v1.bo_blit(dst_bo, src_bo,
+ dst_x0, dst_y0, dst_width, dst_height,
+ src_x0, src_y0, src_width, src_height,
+ flags);
+ else
+ return 0;
+}
+
/**
* A global table of functions and global variables defined in the core GBM
* code that need to be accessed directly by GBM backends.
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
index 1a1e2caecb4..207b6cf9d74 100644
--- a/src/gbm/main/gbm.h
+++ b/src/gbm/main/gbm.h
@@ -266,6 +266,21 @@ enum gbm_bo_flags {
GBM_BO_USE_FRONT_RENDERING = (1 << 6),
};
+/**
+ * Flags to control the behaviour of a blit - these are passed to
+ * gbm_bo_blit().
+ */
+enum gbm_blit_flags {
+ /**
+ * Force blit execution in finite time
+ */
+ GBM_BLIT_FLAG_FLUSH = 0x0001,
+ /**
+ * Flush, and wait for the blit to complete
+ */
+ GBM_BLIT_FLAG_FINISH = 0x0002
+};
+
int
gbm_device_get_fd(struct gbm_device *gbm);
@@ -462,6 +477,12 @@ gbm_surface_destroy(struct gbm_surface *surface);
char *
gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc);
+int
+gbm_bo_blit(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
+ int dst_x0, int dst_y0, int dst_width, int dst_height,
+ int src_x0, int src_y0, int src_width, int src_height,
+ enum gbm_blit_flags flags);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gbm/main/gbm_abi_check.c b/src/gbm/main/gbm_abi_check.c
index feca0998d9d..0153b5a8754 100644
--- a/src/gbm/main/gbm_abi_check.c
+++ b/src/gbm/main/gbm_abi_check.c
@@ -106,6 +106,21 @@ struct gbm_device_abi0 {
struct gbm_device_v0_abi0 v0;
};
+#define GBM_BACKEND_ABI_VERSION_abi1 1
+struct gbm_device_v1_abi1 {
+ int (*bo_blit)(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
+ int dst_x0, int dst_y0, int dst_width, int dst_height,
+ int src_x0, int src_y0, int src_width, int src_height,
+ enum gbm_blit_flags flags);
+};
+
+struct gbm_device_abi1 {
+ /* Hack to make a gbm_device detectable by its first element. */
+ struct gbm_device *(*dummy)(int);
+ struct gbm_device_v0_abi0 v0;
+ struct gbm_device_v1_abi1 v1;
+};
+
/**
* GBM buffer object interface corresponding to GBM_BACKEND_ABI_VERSION = 0
*
@@ -364,8 +379,11 @@ int main(int argc, char **argv)
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_has_free_buffers);
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_destroy);
+ CHECK_MEMBER_CURRENT(gbm_device_v1, _abi1, bo_blit);
+
/* Size of ABI-versioned substructures verified by above member checks */
- CHECK_SIZE_CURRENT (gbm_device, _abi0);
+ CHECK_SIZE (gbm_device, _abi0, _abi1);
+ CHECK_SIZE_CURRENT (gbm_device, _abi1);
/* Check current gbm_bo ABI against gbm_bo_abi0*/
diff --git a/src/gbm/main/gbm_backend_abi.h b/src/gbm/main/gbm_backend_abi.h
index 222ce3404cb..17f5e0ca808 100644
--- a/src/gbm/main/gbm_backend_abi.h
+++ b/src/gbm/main/gbm_backend_abi.h
@@ -157,6 +157,13 @@ struct gbm_device_v0 {
void (*surface_destroy)(struct gbm_surface *surface);
};
+struct gbm_device_v1 {
+ int (*bo_blit)(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
+ int dst_x0, int dst_y0, int dst_width, int dst_height,
+ int src_x0, int src_y0, int src_width, int src_height,
+ enum gbm_blit_flags flags);
+};
+
/**
* The device used for the memory allocation.
*
@@ -169,6 +176,7 @@ struct gbm_device {
/* Hack to make a gbm_device detectable by its first element. */
struct gbm_device *(*dummy)(int);
struct gbm_device_v0 v0;
+ struct gbm_device_v1 v1;
};
/**
--
2.17.1

View file

@ -0,0 +1,44 @@
From ec4f98f3c33f8583ab3208d0c1c209a081433627 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Fri, 1 Dec 2017 08:31:15 +0000
Subject: [PATCH 018/168] gbm: don't assert if DRI context creation fails
If the DRI backend fails to create a DRI context, return an error,
rather than asserting.
---
src/gbm/backends/dri/gbm_dri.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index 6dad8d97d17..53edc1928d8 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -1302,8 +1302,11 @@ gbm_dri_bo_map(struct gbm_bo *_bo,
if (!dri->context)
dri->context = dri->dri2->createNewContext(dri->screen, NULL,
NULL, NULL);
- assert(dri->context);
mtx_unlock(&dri->mutex);
+ if (!dri->context) {
+ errno = ENOSYS;
+ return NULL;
+ }
/* GBM flags and DRI flags are the same, so just pass them on */
return dri->image->mapImage(dri->context, bo->image, x, y,
@@ -1431,8 +1434,11 @@ gbm_dri_bo_blit(struct gbm_bo *_dst_bo, struct gbm_bo *_src_bo,
if (!dri->context)
dri->context = dri->dri2->createNewContext(dri->screen, NULL,
NULL, NULL);
- assert(dri->context);
mtx_unlock(&dri->mutex);
+ if (!dri->context) {
+ errno = ENOSYS;
+ return 0;
+ }
/* GBM flags and DRI flags are the same, so just pass them on */
dri->image->blitImage(dri->context, dst_bo->image, src_bo->image,
--
2.17.1

View file

@ -0,0 +1,476 @@
From e396d88e6c6576a0a016429c86da06d04fc3a34a Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Fri, 17 Mar 2017 16:23:07 +0000
Subject: [PATCH 019/168] egl/wayland: add pbuffer support
The pbuffer code is based on that in the Surfaceless platform code.
---
src/egl/drivers/dri2/egl_dri2.h | 4 +
src/egl/drivers/dri2/platform_wayland.c | 270 ++++++++++++++++++++----
2 files changed, 236 insertions(+), 38 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 40c2a14d8d8..afb2d7297ca 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -398,6 +398,10 @@ struct dri2_egl_surface
__DRIimage *front;
unsigned int visual;
+#ifdef HAVE_WAYLAND_PLATFORM
+ void *swrast_front;
+#endif
+
int out_fence_fd;
EGLBoolean enable_out_fence;
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 8f1c5101441..775909f6138 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -787,6 +787,99 @@ dri2_wl_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
+static _EGLSurface *
+dri2_wl_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ const EGLint *attrib_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
+ struct dri2_egl_surface *dri2_surf;
+ int visual_idx;
+ const __DRIconfig *config;
+
+ dri2_surf = calloc(1, sizeof *dri2_surf);
+ if (!dri2_surf) {
+ _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
+ return NULL;
+ }
+
+ if (!dri2_init_surface(&dri2_surf->base, disp, EGL_PBUFFER_BIT, conf,
+ attrib_list, false, NULL))
+ goto cleanup_surf;
+
+ config = dri2_get_dri_config(dri2_conf, EGL_PBUFFER_BIT,
+ dri2_surf->base.GLColorspace);
+ if (!config) {
+ _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration");
+ goto cleanup_surf;
+ }
+
+ visual_idx = dri2_wl_visual_idx_from_config(dri2_dpy, config, false);
+ assert(visual_idx != -1);
+
+ if (dri2_dpy->wl_dmabuf || dri2_dpy->wl_drm) {
+ dri2_surf->format = dri2_wl_visuals[visual_idx].wl_drm_format;
+ } else {
+ assert(dri2_dpy->wl_shm);
+ dri2_surf->format = dri2_wl_visuals[visual_idx].wl_shm_format;
+ }
+
+ if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf))
+ goto cleanup_surf;
+
+ return &dri2_surf->base;
+
+ cleanup_surf:
+ free(dri2_surf);
+
+ return NULL;
+}
+
+static int
+allocate_front_buffer(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf,
+ EGLBoolean need_name)
+{
+ int use_flags = need_name ? __DRI_IMAGE_USE_SHARE : 0;
+ int visual_idx;
+ unsigned int dri_image_format;
+
+ visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
+ assert(visual_idx != -1);
+ dri_image_format = dri2_wl_visuals[visual_idx].dri_image_format;
+
+ if (!dri2_surf->front)
+ dri2_surf->front = dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ dri_image_format,
+ use_flags,
+ NULL);
+ if (!dri2_surf->front) {
+ _eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+free_front_buffer(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf)
+{
+ if (dri2_surf->front) {
+ dri2_dpy->image->destroyImage(dri2_surf->front);
+ dri2_surf->front = NULL;
+ }
+}
+
+static void
+swrast_free_front_buffer(struct dri2_egl_surface *dri2_surf)
+{
+ free(dri2_surf->swrast_front);
+ dri2_surf->swrast_front = NULL;
+}
+
/**
* Called via eglDestroySurface(), drv->DestroySurface().
*/
@@ -813,6 +906,9 @@ dri2_wl_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
if (dri2_dpy->dri2)
dri2_egl_surface_free_local_buffers(dri2_surf);
+ free_front_buffer(dri2_dpy, dri2_surf);
+ swrast_free_front_buffer(dri2_surf);
+
if (dri2_surf->throttle_callback)
wl_callback_destroy(dri2_surf->throttle_callback);
@@ -822,8 +918,10 @@ dri2_wl_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dri2_surf->wl_win->destroy_window_callback = NULL;
}
- wl_proxy_wrapper_destroy(dri2_surf->wl_surface_wrapper);
- wl_proxy_wrapper_destroy(dri2_surf->wl_dpy_wrapper);
+ if (dri2_surf->wl_surface_wrapper)
+ wl_proxy_wrapper_destroy(dri2_surf->wl_surface_wrapper);
+ if (dri2_surf->wl_dpy_wrapper)
+ wl_proxy_wrapper_destroy(dri2_surf->wl_dpy_wrapper);
if (dri2_surf->wl_drm_wrapper)
wl_proxy_wrapper_destroy(dri2_surf->wl_drm_wrapper);
if (dri2_surf->wl_dmabuf_feedback) {
@@ -831,7 +929,8 @@ dri2_wl_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dmabuf_feedback_fini(&dri2_surf->dmabuf_feedback);
dmabuf_feedback_fini(&dri2_surf->pending_dmabuf_feedback);
}
- wl_event_queue_destroy(dri2_surf->wl_queue);
+ if (dri2_surf->wl_queue)
+ wl_event_queue_destroy(dri2_surf->wl_queue);
dri2_fini_surface(surf);
free(surf);
@@ -1091,20 +1190,16 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
static void
-back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
+bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy, unsigned int attachment,
+ __DRIimage *image, __DRIbuffer *buffer)
{
- struct dri2_egl_display *dri2_dpy =
- dri2_egl_display(dri2_surf->base.Resource.Display);
- __DRIimage *image;
int name, pitch, format;
- image = dri2_surf->back->dri_image;
-
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
- buffer->attachment = __DRI_BUFFER_BACK_LEFT;
+ buffer->attachment = attachment;
buffer->name = name;
buffer->pitch = pitch;
buffer->flags = 0;
@@ -1125,12 +1220,28 @@ back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
*/
#define BUFFER_TRIM_AGE_HYSTERESIS 20
-static int
-update_buffers(struct dri2_egl_surface *dri2_surf)
+static void
+back_bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf,
+ __DRIbuffer *buffer)
{
- struct dri2_egl_display *dri2_dpy =
- dri2_egl_display(dri2_surf->base.Resource.Display);
+ bo_to_dri_buffer(dri2_dpy, __DRI_BUFFER_BACK_LEFT,
+ dri2_surf->back->dri_image, buffer);
+}
+
+static void
+front_bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf,
+ __DRIbuffer *buffer)
+{
+ bo_to_dri_buffer(dri2_dpy, __DRI_BUFFER_FRONT_LEFT,
+ dri2_surf->front, buffer);
+}
+static int
+update_buffers(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf)
+{
if (dri2_surf->wl_win &&
(dri2_surf->base.Width != dri2_surf->wl_win->width ||
dri2_surf->base.Height != dri2_surf->wl_win->height)) {
@@ -1176,12 +1287,13 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
}
static int
-update_buffers_if_needed(struct dri2_egl_surface *dri2_surf)
+update_buffers_if_needed(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf)
{
if (dri2_surf->back != NULL)
return 0;
- return update_buffers(dri2_surf);
+ return update_buffers(dri2_dpy, dri2_surf);
}
static __DRIbuffer *
@@ -1191,17 +1303,25 @@ dri2_wl_get_buffers_with_format(__DRIdrawable * driDrawable,
int *out_count, void *loaderPrivate)
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
int i, j;
- if (update_buffers_if_needed(dri2_surf) < 0)
- return NULL;
-
for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
__DRIbuffer *local;
switch (attachments[i]) {
case __DRI_BUFFER_BACK_LEFT:
- back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0)
+ return NULL;
+
+ back_bo_to_dri_buffer(dri2_dpy, dri2_surf, &dri2_surf->buffers[j]);
+ break;
+ case __DRI_BUFFER_FRONT_LEFT:
+ if (allocate_front_buffer(dri2_dpy, dri2_surf, EGL_TRUE) < 0)
+ return NULL;
+
+ front_bo_to_dri_buffer(dri2_dpy, dri2_surf, &dri2_surf->buffers[j]);
break;
default:
local = dri2_egl_surface_alloc_local_buffer(dri2_surf, attachments[i],
@@ -1271,12 +1391,30 @@ image_get_buffers(__DRIdrawable *driDrawable,
struct __DRIimageList *buffers)
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
- if (update_buffers_if_needed(dri2_surf) < 0)
- return 0;
+ buffers->image_mask = 0;
+ buffers->front = NULL;
+ buffers->back = NULL;
+
+ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK)
+ {
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0)
+ return 0;
+
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+ buffers->back = dri2_surf->back->dri_image;
+ }
+
+ if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT)
+ {
+ if (allocate_front_buffer(dri2_dpy, dri2_surf, EGL_FALSE) < 0)
+ return 0;
- buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
- buffers->back = dri2_surf->back->dri_image;
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
+ buffers->front = dri2_surf->front;
+ }
return 1;
}
@@ -1524,6 +1662,9 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ if (draw->Type != EGL_WINDOW_BIT)
+ return EGL_TRUE;
+
if (!dri2_surf->wl_win)
return _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_swap_buffers");
@@ -1549,7 +1690,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
/* Make sure we have a back buffer in case we're swapping without ever
* rendering. */
- if (update_buffers_if_needed(dri2_surf) < 0)
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0)
return _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
if (draw->SwapInterval > 0) {
@@ -1630,9 +1771,13 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
static EGLint
dri2_wl_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface)
{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
- if (update_buffers_if_needed(dri2_surf) < 0) {
+ if (surface->Type != EGL_WINDOW_BIT)
+ return 0;
+
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0) {
_eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
return -1;
}
@@ -1987,6 +2132,7 @@ static const struct dri2_egl_display_vtbl dri2_wl_display_vtbl = {
.authenticate = dri2_wl_authenticate,
.create_window_surface = dri2_wl_create_window_surface,
.create_pixmap_surface = dri2_wl_create_pixmap_surface,
+ .create_pbuffer_surface = dri2_wl_create_pbuffer_surface,
.destroy_surface = dri2_wl_destroy_surface,
.swap_interval = dri2_wl_swap_interval,
.create_image = dri2_create_image_khr,
@@ -2030,7 +2176,7 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
continue;
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
- count + 1, EGL_WINDOW_BIT, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
+ count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
if (dri2_conf) {
if (dri2_conf->base.ConfigID == count + 1)
count++;
@@ -2292,6 +2438,23 @@ dri2_wl_swrast_get_stride_for_format(int format, int w)
return w * (dri2_wl_visuals[visual_idx].bpp / 8);
}
+static EGLBoolean
+swrast_allocate_local_buffer(int format, int w, int h, void **data)
+{
+ int stride, size_map;
+ void *data_map;
+
+ stride = dri2_wl_swrast_get_stride_for_format(format, w);
+ size_map = h * stride;
+
+ data_map = malloc(size_map);
+ if (!data_map)
+ return EGL_FALSE;
+
+ *data = data_map;
+ return EGL_TRUE;
+}
+
static EGLBoolean
dri2_wl_swrast_allocate_buffer(struct dri2_egl_surface *dri2_surf,
int format, int w, int h,
@@ -2423,8 +2586,24 @@ swrast_update_buffers(struct dri2_egl_surface *dri2_surf)
return 0;
}
+static int
+swrast_allocate_front_buffer(struct dri2_egl_surface *dri2_surf)
+{
+ if (!dri2_surf->swrast_front) {
+ if (!swrast_allocate_local_buffer(dri2_surf->format,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ &dri2_surf->swrast_front)) {
+ _eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static void*
-dri2_wl_swrast_get_frontbuffer_data(struct dri2_egl_surface *dri2_surf)
+dri2_wl_swrast_get_currentbuffer_data(struct dri2_egl_surface *dri2_surf)
{
/* if there has been a resize: */
if (!dri2_surf->current)
@@ -2494,7 +2673,9 @@ dri2_wl_swrast_get_drawable_info(__DRIdrawable * draw,
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
- (void) swrast_update_buffers(dri2_surf);
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT)
+ (void) swrast_update_buffers(dri2_surf);
+
*x = 0;
*y = 0;
*w = dri2_surf->base.Width;
@@ -2513,7 +2694,11 @@ dri2_wl_swrast_get_image(__DRIdrawable * read,
int dst_stride = copy_width;
char *src, *dst;
- src = dri2_wl_swrast_get_frontbuffer_data(dri2_surf);
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT)
+ src = dri2_wl_swrast_get_currentbuffer_data(dri2_surf);
+ else
+ src = dri2_surf->swrast_front;
+
if (!src) {
memset(data, 0, copy_width * h);
return;
@@ -2551,14 +2736,20 @@ dri2_wl_swrast_put_image2(__DRIdrawable * draw, int op,
assert(copy_width <= stride);
- (void) swrast_update_buffers(dri2_surf);
- dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
+ (void) swrast_update_buffers(dri2_surf);
+ dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
- /* partial copy, copy old content */
- if (copy_width < dst_stride)
- dri2_wl_swrast_get_image(draw, 0, 0,
- dri2_surf->base.Width, dri2_surf->base.Height,
- dst, loaderPrivate);
+ /* partial copy, copy old content */
+ if (copy_width < dst_stride)
+ dri2_wl_swrast_get_image(draw, 0, 0,
+ dri2_surf->base.Width, dri2_surf->base.Height,
+ dst, loaderPrivate);
+ } else {
+ (void) swrast_allocate_front_buffer(dri2_surf);
+ dst = dri2_surf->swrast_front;
+ assert(dst);
+ }
dst += x_offset;
dst += y * dst_stride;
@@ -2576,7 +2767,9 @@ dri2_wl_swrast_put_image2(__DRIdrawable * draw, int op,
src += stride;
dst += dst_stride;
}
- dri2_wl_swrast_commit_backbuffer(dri2_surf);
+
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT)
+ dri2_wl_swrast_commit_backbuffer(dri2_surf);
}
static void
@@ -2648,6 +2841,7 @@ static const struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = {
.authenticate = NULL,
.create_window_surface = dri2_wl_create_window_surface,
.create_pixmap_surface = dri2_wl_create_pixmap_surface,
+ .create_pbuffer_surface = dri2_wl_create_pbuffer_surface,
.destroy_surface = dri2_wl_destroy_surface,
.create_image = dri2_create_image_khr,
.swap_buffers = dri2_wl_swrast_swap_buffers,
--
2.17.1

View file

@ -0,0 +1,29 @@
From 87172ae62c79dcd5b384d1a916dc06f81ebc23e2 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 25 Sep 2017 15:58:49 +0100
Subject: [PATCH 020/168] egl: eglBindAPI workaround for dEQP bug
dEQP relies on eglBindAPI to only return true if the API can
successfully be used to create contexts, which the spec does not
require.
Until dEQP is fixed, just disable GL on non-X11 platforms.
---
src/egl/main/eglcurrent.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index d813a46d9ab..c03798eaeac 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -72,7 +72,7 @@ struct _egl_thread_info
static inline EGLBoolean
_eglIsApiValid(EGLenum api)
{
-#ifdef ANDROID
+#ifndef HAVE_X11_PLATFORM
/* OpenGL is not a valid/supported API on Android */
return api == EGL_OPENGL_ES_API;
#else
--
2.17.1

View file

@ -0,0 +1,56 @@
From 40cf908ef114f8c590ee3419153f41b08b208350 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 30 Jan 2018 10:25:11 +0000
Subject: [PATCH 021/168] GL_EXT_multi_draw_indirect entry points
---
src/mapi/glapi/gen/es_EXT.xml | 19 +++++++++++++++++++
src/mapi/glapi/gen/static_data.py | 2 ++
2 files changed, 21 insertions(+)
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index b59e85d3281..6ff5432e029 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1140,6 +1140,25 @@
</category>
+<category name="GL_EXT_multi_draw_indirect" number="205">
+
+ <function name="MultiDrawArraysIndirectEXT" es2="3.1" exec="dynamic">
+ <param name="mode" type="GLenum"/>
+ <param name="indirect" type="const GLvoid *"/>
+ <param name="drawcount" type="GLsizei"/>
+ <param name="stride" type="GLsizei"/>
+ </function>
+
+ <function name="MultiDrawElementsIndirectEXT" es2="3.1" exec="dynamic">
+ <param name="mode" type="GLenum"/>
+ <param name="type" type="GLenum"/>
+ <param name="indirect" type="const GLvoid *"/>
+ <param name="drawcount" type="GLsizei"/>
+ <param name="stride" type="GLsizei"/>
+ </function>
+
+</category>
+
<category name="GL_EXT_copy_image" number="208">
<function name="CopyImageSubDataEXT" alias="CopyImageSubData" es2="3.0">
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 2255385128c..dd4a802c496 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1715,6 +1715,8 @@ offsets = {
"FramebufferTextureLayerDownsampleIMG" : 1679,
"FramebufferTextureMultiviewOVR" : 1680,
"FramebufferTextureMultisampleMultiviewOVR" : 1681,
+ "MultiDrawArraysIndirectEXT" : 1682,
+ "MultiDrawElementsIndirectEXT" : 1683,
}
functions = [
--
2.17.1

View file

@ -0,0 +1,541 @@
From 0e502a3fc9d61e6646730b0d77e4e96711bf2d7f Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Fri, 22 Dec 2017 17:17:50 +0000
Subject: [PATCH 022/168] dri: add support for YUV DRI config
This is prerequisite for adding support for EGL_EXT_yuv_surface.
This also adds support for NV12 and NV21 EGL configs.
---
include/GL/internal/dri_interface.h | 48 +++++++++-
src/gallium/frontends/dri/dri_screen.c | 121 +++++++++++++++++++++++-
src/gallium/frontends/dri/dri_util.c | 12 ++-
src/gallium/frontends/pvr/dri_support.h | 5 +
src/gallium/frontends/pvr/pvrutil.c | 34 +++++++
src/gallium/include/pipe/p_format.h | 4 +
src/mesa/main/format_info.py | 2 +-
src/mesa/main/formats.c | 13 +++
src/mesa/main/formats.csv | 6 ++
src/mesa/main/formats.h | 15 +++
src/mesa/main/glconfig.h | 9 ++
11 files changed, 262 insertions(+), 7 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 9f7d805825f..f049fa76431 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -730,7 +730,13 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_GREEN_SHIFT 51
#define __DRI_ATTRIB_BLUE_SHIFT 52
#define __DRI_ATTRIB_ALPHA_SHIFT 53
-#define __DRI_ATTRIB_MAX 54
+#define __DRI_ATTRIB_YUV_ORDER 54
+#define __DRI_ATTRIB_YUV_NUMBER_OF_PLANES 55
+#define __DRI_ATTRIB_YUV_SUBSAMPLE 56
+#define __DRI_ATTRIB_YUV_DEPTH_RANGE 57
+#define __DRI_ATTRIB_YUV_CSC_STANDARD 58
+#define __DRI_ATTRIB_YUV_PLANE_BPP 59
+#define __DRI_ATTRIB_MAX 60
/* __DRI_ATTRIB_RENDER_TYPE */
#define __DRI_ATTRIB_RGBA_BIT 0x01
@@ -738,6 +744,7 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_LUMINANCE_BIT 0x04
#define __DRI_ATTRIB_FLOAT_BIT 0x08
#define __DRI_ATTRIB_UNSIGNED_FLOAT_BIT 0x10
+#define __DRI_ATTRIB_YUV_BIT 0x20
/* __DRI_ATTRIB_CONFIG_CAVEAT */
#define __DRI_ATTRIB_SLOW_BIT 0x01
@@ -764,6 +771,39 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_SWAP_COPY 0x8062
#define __DRI_ATTRIB_SWAP_UNDEFINED 0x8063
+/* __DRI_ATTRIB_YUV_ORDER */
+#define __DRI_ATTRIB_YUV_ORDER_NONE 0x0
+#define __DRI_ATTRIB_YUV_ORDER_YUV_BIT 0x1
+#define __DRI_ATTRIB_YUV_ORDER_YVU_BIT 0x2
+#define __DRI_ATTRIB_YUV_ORDER_YUYV_BIT 0x4
+#define __DRI_ATTRIB_YUV_ORDER_UYVY_BIT 0x8
+#define __DRI_ATTRIB_YUV_ORDER_YVYU_BIT 0x10
+#define __DRI_ATTRIB_YUV_ORDER_VYUY_BIT 0x20
+#define __DRI_ATTRIB_YUV_ORDER_AYUV_BIT 0x40
+
+/* __DRI_ATTRIB_YUV_SUBSAMPLE */
+#define __DRI_ATTRIB_YUV_SUBSAMPLE_NONE 0x0
+#define __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT 0x1
+#define __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT 0x2
+#define __DRI_ATTRIB_YUV_SUBSAMPLE_4_4_4_BIT 0x4
+
+/* __DRI_ATTRIB_YUV_DEPTH_RANGE */
+#define __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE 0x0
+#define __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT 0x1
+#define __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT 0x2
+
+/* __DRI_ATTRIB_YUV_CSC_STANDARD */
+#define __DRI_ATTRIB_YUV_CSC_STANDARD_NONE 0x0
+#define __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT 0x1
+#define __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT 0x2
+#define __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT 0x4
+
+/* __DRI_ATTRIB_YUV_PLANE_BPP */
+#define __DRI_ATTRIB_YUV_PLANE_BPP_NONE 0x0
+#define __DRI_ATTRIB_YUV_PLANE_BPP_0_BIT 0x1
+#define __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT 0x2
+#define __DRI_ATTRIB_YUV_PLANE_BPP_10_BIT 0x4
+
/**
* This extension defines the core DRI functionality.
*
@@ -1232,6 +1272,12 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FORMAT_ARGB4444 0x1019
#define __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG 0x101a
#define __DRI_IMAGE_FORMAT_BGR888 0x101b
+#define __DRI_IMAGE_FORMAT_NV12 0x101c
+#define __DRI_IMAGE_FORMAT_NV21 0x101d
+#define __DRI_IMAGE_FORMAT_YU12 0x101e
+#define __DRI_IMAGE_FORMAT_YV12 0x101f
+#define __DRI_IMAGE_FORMAT_YVYU 0x1020
+#define __DRI_IMAGE_FORMAT_VYUY 0x1021
#define __DRI_IMAGE_USE_SHARE 0x0001
#define __DRI_IMAGE_USE_SCANOUT 0x0002
diff --git a/src/gallium/frontends/dri/dri_screen.c b/src/gallium/frontends/dri/dri_screen.c
index 27a8cd88efc..d4a61ceffb8 100644
--- a/src/gallium/frontends/dri/dri_screen.c
+++ b/src/gallium/frontends/dri/dri_screen.c
@@ -137,6 +137,21 @@ dri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap)
* This forces 32-bit color to have 24-bit depth, and
* 16-bit color to have 16-bit depth.
*
+ * \param yuv_depth_range YUV pixel depth range. For non-YUV pixel formats this
+ * should be \c __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE.
+ * Otherwise valid values are
+ * \c __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT and
+ * \c __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT. See the
+ * EGL_EXT_yuv_surface extension spec for more details.
+ * \param yuv_csc_standard YUV color conversion standard. For non-YUV pixel
+ * formats this should be
+ * \c __DRI_ATTRIB_YUV_CSC_STANDARD_NONE. Otherwise
+ * valid values are
+ * \c __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT,
+ * \c __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT and
+ * \c __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT. See the
+ * EGL_EXT_yuv_surface extension spec for more details.
+ *
* \returns
* Pointer to any array of pointers to the \c __DRIconfig structures created
* for the specified formats. If there is an error, \c NULL is returned.
@@ -149,7 +164,8 @@ driCreateConfigs(mesa_format format,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
const uint8_t * msaa_samples, unsigned num_msaa_modes,
- GLboolean enable_accum, GLboolean color_depth_match)
+ GLboolean enable_accum, GLboolean color_depth_match,
+ GLint yuv_depth_range, GLint yuv_csc_standard)
{
static const struct {
uint32_t masks[4];
@@ -188,6 +204,9 @@ driCreateConfigs(mesa_format format,
/* MESA_FORMAT_RGBA_FLOAT16 */
{{ 0, 0, 0, 0},
{ 0, 16, 32, 48 }},
+ /* Mesa YUV formats */
+ {{ 0, 0, 0, 0 },
+ { -1, -1, -1, -1}},
};
const uint32_t * masks;
@@ -201,6 +220,11 @@ driCreateConfigs(mesa_format format,
int green_bits;
int blue_bits;
int alpha_bits;
+ int yuv_order = __DRI_ATTRIB_YUV_ORDER_NONE;
+ int yuv_num_planes = 0;
+ int yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_NONE;
+ int yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_NONE;
+ bool is_yuv = false;
bool is_srgb;
bool is_float;
@@ -253,6 +277,78 @@ driCreateConfigs(mesa_format format,
masks = format_table[8].masks;
shifts = format_table[8].shifts;
break;
+ case MESA_FORMAT_YCBCR:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_YUYV_BIT;
+ yuv_num_planes = 1;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
+ case MESA_FORMAT_YUV420_2PLANE:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT;
+ yuv_num_planes = 2;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
+ case MESA_FORMAT_YVU420_2PLANE:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT;
+ yuv_num_planes = 2;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
+ case MESA_FORMAT_YUV420_3PLANE:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT;
+ yuv_num_planes = 3;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
+ case MESA_FORMAT_YVU420_3PLANE:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT;
+ yuv_num_planes = 3;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
+ case MESA_FORMAT_YCBCR_REV:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_UYVY_BIT;
+ yuv_num_planes = 1;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
+ case MESA_FORMAT_VYUY:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_VYUY_BIT;
+ yuv_num_planes = 1;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
+ case MESA_FORMAT_YVYU:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_YVYU_BIT;
+ yuv_num_planes = 1;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
default:
fprintf(stderr, "[%s:%u] Unknown framebuffer type %s (%d).\n",
__func__, __LINE__,
@@ -308,7 +404,11 @@ driCreateConfigs(mesa_format format,
modes->greenShift = shifts[1];
modes->blueShift = shifts[2];
modes->alphaShift = shifts[3];
- modes->rgbBits = modes->redBits + modes->greenBits
+
+ if (is_yuv)
+ modes->rgbBits = 8;
+ else
+ modes->rgbBits = modes->redBits + modes->greenBits
+ modes->blueBits + modes->alphaBits;
modes->accumRedBits = 16 * j;
@@ -319,6 +419,8 @@ driCreateConfigs(mesa_format format,
modes->stencilBits = stencil_bits[k];
modes->depthBits = depth_bits[k];
+ modes->rgbMode = !is_yuv;
+
if (db_modes[i] == __DRI_ATTRIB_SWAP_NONE) {
modes->doubleBufferMode = GL_FALSE;
modes->swapMethod = __DRI_ATTRIB_SWAP_UNDEFINED;
@@ -331,6 +433,13 @@ driCreateConfigs(mesa_format format,
modes->samples = msaa_samples[h];
modes->sRGBCapable = is_srgb;
+
+ modes->YUVOrder = yuv_order;
+ modes->YUVNumberOfPlanes = yuv_num_planes;
+ modes->YUVSubsample = yuv_subsample;
+ modes->YUVDepthRange = yuv_depth_range;
+ modes->YUVCSCStandard = yuv_csc_standard;
+ modes->YUVPlaneBPP = yuv_plane_bpp;
}
}
}
@@ -556,7 +665,9 @@ dri_fill_in_modes(struct dri_screen *screen)
depth_buffer_factor, back_buffer_modes,
ARRAY_SIZE(back_buffer_modes),
msaa_modes, 1,
- GL_TRUE, !mixed_color_depth);
+ GL_TRUE, !mixed_color_depth,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
/* Multi-sample configs without an accumulation buffer. */
@@ -566,7 +677,9 @@ dri_fill_in_modes(struct dri_screen *screen)
depth_buffer_factor, back_buffer_modes,
ARRAY_SIZE(back_buffer_modes),
msaa_modes+1, num_msaa_modes-1,
- GL_FALSE, !mixed_color_depth);
+ GL_FALSE, !mixed_color_depth,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
}
}
diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c
index 6c3ce760ab0..32ae2b6fec7 100644
--- a/src/gallium/frontends/dri/dri_util.c
+++ b/src/gallium/frontends/dri/dri_util.c
@@ -302,7 +302,11 @@ driGetConfigAttribIndex(const __DRIconfig *config,
SIMPLE_CASE(__DRI_ATTRIB_SAMPLES, samples);
case __DRI_ATTRIB_RENDER_TYPE:
/* no support for color index mode */
- *value = __DRI_ATTRIB_RGBA_BIT;
+ if (config->modes.rgbMode)
+ *value = __DRI_ATTRIB_RGBA_BIT;
+ else
+ *value = __DRI_ATTRIB_YUV_BIT;
+
if (config->modes.floatMode)
*value |= __DRI_ATTRIB_FLOAT_BIT;
break;
@@ -370,6 +374,12 @@ driGetConfigAttribIndex(const __DRIconfig *config,
SIMPLE_CASE(__DRI_ATTRIB_GREEN_SHIFT, greenShift);
SIMPLE_CASE(__DRI_ATTRIB_BLUE_SHIFT, blueShift);
SIMPLE_CASE(__DRI_ATTRIB_ALPHA_SHIFT, alphaShift);
+ SIMPLE_CASE(__DRI_ATTRIB_YUV_ORDER, YUVOrder);
+ SIMPLE_CASE(__DRI_ATTRIB_YUV_NUMBER_OF_PLANES, YUVNumberOfPlanes);
+ SIMPLE_CASE(__DRI_ATTRIB_YUV_SUBSAMPLE, YUVSubsample);
+ SIMPLE_CASE(__DRI_ATTRIB_YUV_DEPTH_RANGE, YUVDepthRange);
+ SIMPLE_CASE(__DRI_ATTRIB_YUV_CSC_STANDARD, YUVCSCStandard);
+ SIMPLE_CASE(__DRI_ATTRIB_YUV_PLANE_BPP, YUVPlaneBPP);
default:
/* XXX log an error or smth */
return GL_FALSE;
diff --git a/src/gallium/frontends/pvr/dri_support.h b/src/gallium/frontends/pvr/dri_support.h
index 955f01cb7d5..3cc8f290d4d 100644
--- a/src/gallium/frontends/pvr/dri_support.h
+++ b/src/gallium/frontends/pvr/dri_support.h
@@ -92,6 +92,11 @@ typedef enum
#define PVRDRI_MESA_FORMAT_YVU420_2PLANE 8
#define PVRDRI_MESA_FORMAT_B8G8R8A8_SRGB 9
#define PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB 10
+#define PVRDRI_MESA_FORMAT_YUV420_3PLANE 11
+#define PVRDRI_MESA_FORMAT_YVU420_3PLANE 12
+#define PVRDRI_MESA_FORMAT_YCBCR_REV 13
+#define PVRDRI_MESA_FORMAT_YVYU 14
+#define PVRDRI_MESA_FORMAT_VYUY 15
typedef struct __DRIimageRec __DRIimage;
diff --git a/src/gallium/frontends/pvr/pvrutil.c b/src/gallium/frontends/pvr/pvrutil.c
index e1a1d1cac07..39f0d1e21fe 100644
--- a/src/gallium/frontends/pvr/pvrutil.c
+++ b/src/gallium/frontends/pvr/pvrutil.c
@@ -113,6 +113,16 @@ PVRDRIMesaFormatToMesaFormat(int pvrdri_mesa_format)
return MESA_FORMAT_B8G8R8A8_SRGB;
case PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB:
return MESA_FORMAT_R8G8B8A8_SRGB;
+ case PVRDRI_MESA_FORMAT_YUV420_3PLANE:
+ return MESA_FORMAT_YUV420_3PLANE;
+ case PVRDRI_MESA_FORMAT_YVU420_3PLANE:
+ return MESA_FORMAT_YVU420_3PLANE;
+ case PVRDRI_MESA_FORMAT_YCBCR_REV:
+ return MESA_FORMAT_YCBCR_REV;
+ case PVRDRI_MESA_FORMAT_YVYU:
+ return MESA_FORMAT_YVYU;
+ case PVRDRI_MESA_FORMAT_VYUY:
+ return MESA_FORMAT_VYUY;
default:
__driUtilMessage("%s: Unknown format: %d", __func__, pvrdri_mesa_format);
break;
@@ -171,6 +181,18 @@ PVRDRIFormatToFourCC(int dri_format)
return DRM_FORMAT_BGR888;
case __DRI_IMAGE_FORMAT_AXBXGXRX106106106106:
return DRM_FORMAT_AXBXGXRX106106106106;
+ case __DRI_IMAGE_FORMAT_NV12:
+ return DRM_FORMAT_NV12;
+ case __DRI_IMAGE_FORMAT_NV21:
+ return DRM_FORMAT_NV21;
+ case __DRI_IMAGE_FORMAT_YU12:
+ return DRM_FORMAT_YUV420;
+ case __DRI_IMAGE_FORMAT_YV12:
+ return DRM_FORMAT_YVU420;
+ case __DRI_IMAGE_FORMAT_YVYU:
+ return DRM_FORMAT_YVYU;
+ case __DRI_IMAGE_FORMAT_VYUY:
+ return DRM_FORMAT_VYUY;
default:
__driUtilMessage("%s: Unknown format: %d", __func__, dri_format);
break;
@@ -229,6 +251,18 @@ PVRDRIFourCCToDRIFormat(int iFourCC)
return __DRI_IMAGE_FORMAT_BGR888;
case DRM_FORMAT_AXBXGXRX106106106106:
return __DRI_IMAGE_FORMAT_AXBXGXRX106106106106;
+ case DRM_FORMAT_NV12:
+ return __DRI_IMAGE_FORMAT_NV12;
+ case DRM_FORMAT_NV21:
+ return __DRI_IMAGE_FORMAT_NV21;
+ case DRM_FORMAT_YUV420:
+ return __DRI_IMAGE_FORMAT_YU12;
+ case DRM_FORMAT_YVU420:
+ return __DRI_IMAGE_FORMAT_YV12;
+ case DRM_FORMAT_YVYU:
+ return __DRI_IMAGE_FORMAT_YVYU;
+ case DRM_FORMAT_VYUY:
+ return __DRI_IMAGE_FORMAT_VYUY;
default:
__driUtilMessage("%s: Unknown format: %d", __func__, iFourCC);
break;
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index 3387d3091ab..7a0e19126a7 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -189,6 +189,8 @@ enum pipe_format {
PIPE_FORMAT_L16_UNORM, /**< ushort luminance */
PIPE_FORMAT_UYVY,
PIPE_FORMAT_YUYV,
+ PIPE_FORMAT_YVYU,
+ PIPE_FORMAT_VYUY,
PIPE_FORMAT_Z16_UNORM,
PIPE_FORMAT_Z16_UNORM_S8_UINT,
PIPE_FORMAT_Z32_UNORM,
@@ -627,6 +629,8 @@ pipe_format_to_chroma_format(enum pipe_format format)
return PIPE_VIDEO_CHROMA_FORMAT_420;
case PIPE_FORMAT_UYVY:
case PIPE_FORMAT_YUYV:
+ case PIPE_FORMAT_VYUY:
+ case PIPE_FORMAT_YVYU:
case PIPE_FORMAT_YV16:
case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
case PIPE_FORMAT_Y8_U8V8_422_UNORM:
diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py
index 37b46a27c31..9aa1bb9fc63 100644
--- a/src/mesa/main/format_info.py
+++ b/src/mesa/main/format_info.py
@@ -27,7 +27,7 @@ import sys
def get_gl_base_format(fmat):
if fmat.name == 'MESA_FORMAT_NONE':
return 'GL_NONE'
- elif fmat.name in ['MESA_FORMAT_YCBCR', 'MESA_FORMAT_YCBCR_REV']:
+ elif fmat.name in ['MESA_FORMAT_YCBCR', 'MESA_FORMAT_YCBCR_REV', 'MESA_FORMAT_YUV420_2PLANE', 'MESA_FORMAT_YVU420_2PLANE', 'MESA_FORMAT_YUV420_3PLANE', 'MESA_FORMAT_YVU420_3PLANE', 'MESA_FORMAT_YVYU', 'MESA_FORMAT_VYUY']:
return 'GL_YCBCR_MESA'
elif fmat.has_channel('r'):
if fmat.has_channel('g'):
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index a46572513f0..79402f7fb8c 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -1019,6 +1019,8 @@ _mesa_uncompressed_format_to_type_and_comps(mesa_format format,
case MESA_FORMAT_YCBCR:
case MESA_FORMAT_YCBCR_REV:
+ case MESA_FORMAT_YVYU:
+ case MESA_FORMAT_VYUY:
case MESA_FORMAT_RG_RB_UNORM8:
case MESA_FORMAT_GR_BR_UNORM8:
*datatype = GL_UNSIGNED_SHORT;
@@ -1447,6 +1449,17 @@ _mesa_format_matches_format_and_type(mesa_format mformat,
if (error)
*error = GL_NO_ERROR;
+ switch (mformat) {
+ case MESA_FORMAT_YUV420_2PLANE:
+ case MESA_FORMAT_YVU420_2PLANE:
+ case MESA_FORMAT_YUV420_3PLANE:
+ case MESA_FORMAT_YVU420_3PLANE:
+ return false;
+
+ default:
+ break;
+ }
+
if (_mesa_is_format_compressed(mformat)) {
if (error)
*error = GL_INVALID_ENUM;
diff --git a/src/mesa/main/formats.csv b/src/mesa/main/formats.csv
index 21cdea26e08..d1532b19b06 100644
--- a/src/mesa/main/formats.csv
+++ b/src/mesa/main/formats.csv
@@ -92,6 +92,12 @@ MESA_FORMAT_A2R10G10B10_UNORM , packed, 1, 1, 1, un2 , un10, un10, u
MESA_FORMAT_YCBCR , other , 1, 1, 1, x16 , , , , xyzw, yuv
MESA_FORMAT_YCBCR_REV , other , 1, 1, 1, x16 , , , , xyzw, yuv
+MESA_FORMAT_YUV420_2PLANE , other , 1, 1, 1, x8 , , , , y___, yuv
+MESA_FORMAT_YVU420_2PLANE , other , 1, 1, 1, x8 , , , , y___, yuv
+MESA_FORMAT_YUV420_3PLANE , other , 1, 1, 1, x8 , , , , y___, yuv
+MESA_FORMAT_YVU420_3PLANE , other , 1, 1, 1, x8 , , , , y___, yuv
+MESA_FORMAT_YVYU , other , 1, 1, 1, x16 , , , , xyzw, yuv
+MESA_FORMAT_VYUY , other , 1, 1, 1, x16 , , , , xyzw, yuv
MESA_FORMAT_RG_RB_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb
MESA_FORMAT_GR_BR_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index aee6217621d..6c07281c20e 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -617,6 +617,21 @@ typedef enum pipe_format mesa_format;
#define MESA_FORMAT_ATC_RGB PIPE_FORMAT_ATC_RGB
#define MESA_FORMAT_ATC_RGBA_EXPLICIT PIPE_FORMAT_ATC_RGBA_EXPLICIT
#define MESA_FORMAT_ATC_RGBA_INTERPOLATED PIPE_FORMAT_ATC_RGBA_INTERPOLATED
+#define MESA_FORMAT_YVYU PIPE_FORMAT_YVYU
+#define MESA_FORMAT_VYUY PIPE_FORMAT_VYUY
+
+#define HAVE_MESA_FORMAT_YUV420_2PLANE
+#define MESA_FORMAT_YUV420_2PLANE PIPE_FORMAT_NV12
+
+#define HAVE_MESA_FORMAT_YVU420_2PLANE
+#define MESA_FORMAT_YVU420_2PLANE PIPE_FORMAT_NV21
+
+#define HAVE_MESA_FORMAT_YUV420_3PLANE
+#define MESA_FORMAT_YUV420_3PLANE PIPE_FORMAT_IYUV
+
+#define HAVE_MESA_FORMAT_YVU420_3PLANE
+#define MESA_FORMAT_YVU420_3PLANE PIPE_FORMAT_YV12
+
#define MESA_FORMAT_COUNT PIPE_FORMAT_COUNT
/* Packed to array format adapters */
diff --git a/src/mesa/main/glconfig.h b/src/mesa/main/glconfig.h
index 80414d5d78e..d54a4f75cfd 100644
--- a/src/mesa/main/glconfig.h
+++ b/src/mesa/main/glconfig.h
@@ -10,6 +10,7 @@
*/
struct gl_config
{
+ GLboolean rgbMode;
GLboolean floatMode;
GLuint doubleBufferMode;
GLuint stereoMode;
@@ -31,6 +32,14 @@ struct gl_config
/* EXT_framebuffer_sRGB */
GLint sRGBCapable;
+
+ /* EXT_yuv_surface */
+ GLint YUVOrder;
+ GLint YUVNumberOfPlanes;
+ GLint YUVSubsample;
+ GLint YUVDepthRange;
+ GLint YUVCSCStandard;
+ GLint YUVPlaneBPP;
};
--
2.17.1

View file

@ -0,0 +1,541 @@
From 76f6b118fe303124dcc5cd4005d3c28f35afbcae Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 20 Dec 2017 17:41:38 +0000
Subject: [PATCH 023/168] egl: add support for EXT_yuv_surface
This implements EXT_yuv_surface but doesn't expose it for any platform.
---
include/GL/internal/dri_interface.h | 1 +
src/egl/drivers/dri2/egl_dri2.c | 83 +++++++++
src/egl/main/eglapi.c | 1 +
src/egl/main/eglconfig.c | 255 +++++++++++++++++++++++++++-
src/egl/main/eglconfig.h | 12 ++
src/egl/main/egldisplay.h | 1 +
6 files changed, 348 insertions(+), 5 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index f049fa76431..a62ccc1b41f 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1023,6 +1023,7 @@ enum dri_loader_cap {
*/
DRI_LOADER_CAP_RGBA_ORDERING,
DRI_LOADER_CAP_FP16,
+ DRI_LOADER_CAP_YUV_SURFACE_IMG = 0x7001,
};
struct __DRIdri2LoaderExtensionRec {
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 5ed9898993b..309265dc14b 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -316,6 +316,7 @@ static const EGLint dri2_to_egl_attribute_map[__DRI_ATTRIB_MAX] = {
[__DRI_ATTRIB_MAX_SWAP_INTERVAL] = EGL_MAX_SWAP_INTERVAL,
[__DRI_ATTRIB_MIN_SWAP_INTERVAL] = EGL_MIN_SWAP_INTERVAL,
[__DRI_ATTRIB_YINVERTED] = EGL_Y_INVERTED_NOK,
+ [__DRI_ATTRIB_YUV_NUMBER_OF_PLANES] = EGL_YUV_NUMBER_OF_PLANES_EXT,
};
const __DRIconfig *
@@ -442,6 +443,8 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
value = EGL_RGB_BUFFER;
else if (value & __DRI_ATTRIB_LUMINANCE_BIT)
value = EGL_LUMINANCE_BUFFER;
+ else if (value & __DRI_ATTRIB_YUV_BIT)
+ value = EGL_YUV_BUFFER_EXT;
else
return NULL;
base.ColorBufferType = value;
@@ -546,6 +549,73 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
if (disp->Extensions.KHR_mutable_render_buffer)
surface_type |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
break;
+
+ case __DRI_ATTRIB_YUV_ORDER:
+ if (value & __DRI_ATTRIB_YUV_ORDER_YUV_BIT)
+ value = EGL_YUV_ORDER_YUV_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_YVU_BIT)
+ value = EGL_YUV_ORDER_YVU_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_YUYV_BIT)
+ value = EGL_YUV_ORDER_YUYV_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_UYVY_BIT)
+ value = EGL_YUV_ORDER_UYVY_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_YVYU_BIT)
+ value = EGL_YUV_ORDER_YVYU_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_VYUY_BIT)
+ value = EGL_YUV_ORDER_VYUY_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_AYUV_BIT)
+ value = EGL_YUV_ORDER_AYUV_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_ORDER_EXT, value);
+ break;
+
+ case __DRI_ATTRIB_YUV_SUBSAMPLE:
+ if (value & __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT)
+ value = EGL_YUV_SUBSAMPLE_4_2_0_EXT;
+ else if (value & __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT)
+ value = EGL_YUV_SUBSAMPLE_4_2_2_EXT;
+ else if (value & __DRI_ATTRIB_YUV_SUBSAMPLE_4_4_4_BIT)
+ value = EGL_YUV_SUBSAMPLE_4_4_4_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_SUBSAMPLE_EXT, value);
+ break;
+
+ case __DRI_ATTRIB_YUV_DEPTH_RANGE:
+ if (value & __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT)
+ value = EGL_YUV_DEPTH_RANGE_LIMITED_EXT;
+ else if (value & __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT)
+ value = EGL_YUV_DEPTH_RANGE_FULL_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_DEPTH_RANGE_EXT, value);
+ break;
+
+ case __DRI_ATTRIB_YUV_CSC_STANDARD:
+ if (value & __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT)
+ value = EGL_YUV_CSC_STANDARD_601_EXT;
+ else if (value & __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT)
+ value = EGL_YUV_CSC_STANDARD_709_EXT;
+ else if (value & __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT)
+ value = EGL_YUV_CSC_STANDARD_2020_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_CSC_STANDARD_EXT, value);
+ break;
+
+ case __DRI_ATTRIB_YUV_PLANE_BPP:
+ if (value & __DRI_ATTRIB_YUV_PLANE_BPP_0_BIT)
+ value = EGL_YUV_PLANE_BPP_0_EXT;
+ else if (value & __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT)
+ value = EGL_YUV_PLANE_BPP_8_EXT;
+ else if (value & __DRI_ATTRIB_YUV_PLANE_BPP_10_BIT)
+ value = EGL_YUV_PLANE_BPP_10_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_PLANE_BPP_EXT, value);
+ break;
+
default:
key = dri2_to_egl_attribute_map[attrib];
if (key != 0)
@@ -584,6 +654,17 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
base.RenderableType = disp->ClientAPIs;
base.Conformant = disp->ClientAPIs;
+ /*
+ * We assume that if dri_config is YUV then GL_EXT_YUV_target must be
+ * supported, which requires OpenGL ES 3.0.
+ */
+ if (base.ColorBufferType == EGL_YUV_BUFFER_EXT) {
+ base.RenderableType &= EGL_OPENGL_ES3_BIT;
+ base.Conformant &= EGL_OPENGL_ES3_BIT;
+ }
+ if (!base.RenderableType)
+ return NULL;
+
base.MinSwapInterval = dri2_dpy->min_swap_interval;
base.MaxSwapInterval = dri2_dpy->max_swap_interval;
@@ -1042,6 +1123,8 @@ dri2_setup_screen(_EGLDisplay *disp)
disp->Extensions.EXT_protected_content =
dri2_renderer_query_integer(dri2_dpy,
__DRI2_RENDERER_HAS_PROTECTED_CONTEXT);
+
+ disp->Extensions.EXT_yuv_surface = EGL_TRUE;
}
void
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 5e69f1cb856..c4dac448b8b 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -569,6 +569,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
_EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
_EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
+ _EGL_CHECK_EXTENSION(EXT_yuv_surface);
_EGL_CHECK_EXTENSION(IMG_context_priority);
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 1c8b01bca8f..86d82851f45 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -258,6 +258,24 @@ static const struct {
{ EGL_COLOR_COMPONENT_TYPE_EXT, ATTRIB_TYPE_ENUM,
ATTRIB_CRITERION_EXACT,
EGL_COLOR_COMPONENT_TYPE_FIXED_EXT },
+ { EGL_YUV_ORDER_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
+ { EGL_YUV_NUMBER_OF_PLANES_EXT, ATTRIB_TYPE_INTEGER,
+ ATTRIB_CRITERION_ATLEAST,
+ 0 },
+ { EGL_YUV_SUBSAMPLE_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
+ { EGL_YUV_DEPTH_RANGE_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
+ { EGL_YUV_CSC_STANDARD_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
+ { EGL_YUV_PLANE_BPP_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
};
@@ -296,6 +314,28 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
if (val > 1 || val < 0)
valid = EGL_FALSE;
break;
+ case EGL_YUV_NUMBER_OF_PLANES_EXT:
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * The allowed values for EGL_YUV_NUMBER_OF_PLANES_EXT must
+ * be greater than zero and not more than three.
+ *
+ * However, it also says:
+ *
+ * Attribute Default Selection Sort Sort
+ * Criteria Order Priority
+ * ---------------------------- ------- --------- ----- --------
+ * EGL_YUV_NUMBER_OF_PLANES_EXT 0 At least None
+ *
+ * This means that we need to allow the value 0 when doing config
+ * matching (where it's essentially treated as EGL_DONT_CARE).
+ * Furthermore, this attribute isn't applicable to non-YUV EGL
+ * color buffer types. Allow 0 through here and then do further
+ * validation later on.
+ */
+ if (val < 0 || val > 3)
+ valid = EGL_FALSE;
+ break;
default:
if (val < 0)
valid = EGL_FALSE;
@@ -318,7 +358,43 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
valid = EGL_FALSE;
break;
case EGL_COLOR_BUFFER_TYPE:
- if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER)
+ if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER &&
+ val != EGL_YUV_BUFFER_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_ORDER_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_ORDER_YUV_EXT && val != EGL_YUV_ORDER_YVU_EXT &&
+ val != EGL_YUV_ORDER_YUYV_EXT && val != EGL_YUV_ORDER_UYVY_EXT &&
+ val != EGL_YUV_ORDER_YVYU_EXT && val != EGL_YUV_ORDER_VYUY_EXT &&
+ val != EGL_YUV_ORDER_AYUV_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_SUBSAMPLE_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_SUBSAMPLE_4_2_0_EXT &&
+ val != EGL_YUV_SUBSAMPLE_4_2_2_EXT &&
+ val != EGL_YUV_SUBSAMPLE_4_4_4_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_DEPTH_RANGE_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_DEPTH_RANGE_LIMITED_EXT &&
+ val != EGL_YUV_DEPTH_RANGE_FULL_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_CSC_STANDARD_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_CSC_STANDARD_601_EXT &&
+ val != EGL_YUV_CSC_STANDARD_709_EXT &&
+ val != EGL_YUV_CSC_STANDARD_2020_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_PLANE_BPP_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_PLANE_BPP_0_EXT &&
+ val != EGL_YUV_PLANE_BPP_8_EXT &&
+ val != EGL_YUV_PLANE_BPP_10_EXT)
valid = EGL_FALSE;
break;
case EGL_COLOR_COMPONENT_TYPE_EXT:
@@ -404,6 +480,11 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
if (conf->LuminanceSize + conf->AlphaSize != conf->BufferSize)
valid = EGL_FALSE;
break;
+ case EGL_YUV_BUFFER_EXT:
+ if (conf->RedSize || conf->GreenSize || conf->BlueSize ||
+ conf->AlphaSize || conf->LuminanceSize)
+ valid = EGL_FALSE;
+ break;
}
if (!valid) {
_eglLog(_EGL_DEBUG, "conflicting color buffer type and channel sizes");
@@ -430,6 +511,88 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
return EGL_FALSE;
}
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * SUBSAMPLE_EXT NUMBER_OF_PLANES_EXT ORDER_EXT PLANE_BPP_EXT
+ * ------------------- -------------------- ----------------- ------------------
+ * SUBSAMPLE_4_2_0_EXT 2 or 3 ORDER_YUV_EXT or PLANE_BPP_8_EXT or
+ * ORDER_YVU_EXT PLANE_BPP_10_EXT
+ */
+ if (conf->YUVSubsampleEXT == EGL_YUV_SUBSAMPLE_4_2_0_EXT) {
+ if ((!for_matching || conf->YUVNumberOfPlanesEXT != 0) &&
+ conf->YUVNumberOfPlanesEXT != 2 &&
+ conf->YUVNumberOfPlanesEXT != 3)
+ valid = EGL_FALSE;
+ if (conf->YUVOrderEXT != EGL_DONT_CARE &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YUV_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YVU_EXT)
+ valid = EGL_FALSE;
+ if (conf->YUVPlaneBPPEXT != EGL_DONT_CARE &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_8_EXT &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_10_EXT)
+ valid = EGL_FALSE;
+ }
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * SUBSAMPLE_EXT NUMBER_OF_PLANES_EXT ORDER_EXT PLANE_BPP_EXT
+ * ------------------- -------------------- ----------------- ------------------
+ * SUBSAMPLE_4_2_2_EXT 1 ORDER_YUYV_EXT or PLANE_BPP_8_EXT or
+ * ORDER_YVYU_EXT or PLANE_BPP_10_EXT
+ * ORDER_UYVY_EXT or
+ * ORDER_VYUY_EXT
+ *
+ * SUBSAMPLE_4_2_2_EXT 2 or 3 ORDER_YUV_EXT or PLANE_BPP_8_EXT or
+ * ORDER_YVU_EXT PLANE_BPP_10_EXT
+ */
+ else if (conf->YUVSubsampleEXT == EGL_YUV_SUBSAMPLE_4_2_2_EXT) {
+ if ((!for_matching || conf->YUVNumberOfPlanesEXT != 0) &&
+ conf->YUVNumberOfPlanesEXT != 1 &&
+ conf->YUVNumberOfPlanesEXT != 2 &&
+ conf->YUVNumberOfPlanesEXT != 3)
+ valid = EGL_FALSE;
+ if (conf->YUVNumberOfPlanesEXT == 1) {
+ if (conf->YUVOrderEXT != EGL_DONT_CARE &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YUYV_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YVYU_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_UYVY_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_VYUY_EXT)
+ valid = EGL_FALSE;
+ } else if (conf->YUVNumberOfPlanesEXT == 2 ||
+ conf->YUVNumberOfPlanesEXT == 3) {
+ if (conf->YUVOrderEXT != EGL_DONT_CARE &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YUV_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YVU_EXT)
+ valid = EGL_FALSE;
+ }
+ if (conf->YUVPlaneBPPEXT != EGL_DONT_CARE &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_8_EXT &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_10_EXT)
+ valid = EGL_FALSE;
+ }
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * SUBSAMPLE_EXT NUMBER_OF_PLANES_EXT ORDER_EXT PLANE_BPP_EXT
+ * ------------------- -------------------- ----------------- ------------------
+ * SUBSAMPLE_4_4_4_EXT 1 ORDER_AYUV_EXT PLANE_BPP_8_EXT or
+ * PLANE_BPP_10_EXT
+ */
+ else if (conf->YUVSubsampleEXT == EGL_YUV_SUBSAMPLE_4_4_4_EXT) {
+ if ((!for_matching || conf->YUVNumberOfPlanesEXT != 0) &&
+ conf->YUVNumberOfPlanesEXT != 1)
+ valid = EGL_FALSE;
+ if (conf->YUVOrderEXT != EGL_DONT_CARE &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_AYUV_EXT)
+ valid = EGL_FALSE;
+ if (conf->YUVPlaneBPPEXT != EGL_DONT_CARE &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_8_EXT &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_10_EXT)
+ valid = EGL_FALSE;
+ }
+ if (!valid) {
+ _eglLog(_EGL_DEBUG, "invalid YUV subsample/num planes/order/bpp combination");
+ return EGL_FALSE;
+ }
+
return valid;
}
@@ -509,6 +672,28 @@ _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
return conf->Display->Extensions.ANDROID_framebuffer_target;
case EGL_RECORDABLE_ANDROID:
return conf->Display->Extensions.ANDROID_recordable;
+ case EGL_YUV_ORDER_EXT:
+ case EGL_YUV_NUMBER_OF_PLANES_EXT:
+ case EGL_YUV_SUBSAMPLE_EXT:
+ case EGL_YUV_DEPTH_RANGE_EXT:
+ case EGL_YUV_CSC_STANDARD_EXT:
+ case EGL_YUV_PLANE_BPP_EXT:
+ return conf->Display->Extensions.EXT_yuv_surface;
+ default:
+ break;
+ }
+
+ return EGL_TRUE;
+}
+
+static inline EGLBoolean
+_eglIsConfigAttribValueValid(_EGLConfig *conf, EGLint attr, EGLint val)
+{
+ switch (attr) {
+ case EGL_COLOR_BUFFER_TYPE:
+ if (!conf->Display->Extensions.EXT_yuv_surface && val == EGL_YUV_BUFFER_EXT)
+ return EGL_FALSE;
+ break;
default:
break;
}
@@ -543,6 +728,9 @@ _eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *disp,
if (!_eglIsConfigAttribValid(conf, attr))
return EGL_FALSE;
+ if (!_eglIsConfigAttribValueValid(conf, attr, val))
+ return EGL_FALSE;
+
_eglSetConfigKey(conf, attr, val);
}
@@ -617,6 +805,7 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
/* the enum values have the desired ordering */
STATIC_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
+ STATIC_ASSERT(EGL_LUMINANCE_BUFFER < EGL_YUV_BUFFER_EXT);
val1 = conf1->ColorBufferType - conf2->ColorBufferType;
if (val1)
return val1;
@@ -636,16 +825,42 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
val1 += conf1->BlueSize;
val2 += conf2->BlueSize;
}
+ if (criteria->AlphaSize > 0) {
+ val1 += conf1->AlphaSize;
+ val2 += conf2->AlphaSize;
+ }
}
- else {
+ else if (conf1->ColorBufferType == EGL_LUMINANCE_BUFFER) {
if (criteria->LuminanceSize > 0) {
val1 += conf1->LuminanceSize;
val2 += conf2->LuminanceSize;
}
+ if (criteria->AlphaSize > 0) {
+ val1 += conf1->AlphaSize;
+ val2 += conf2->AlphaSize;
+ }
}
- if (criteria->AlphaSize > 0) {
- val1 += conf1->AlphaSize;
- val2 += conf2->AlphaSize;
+ else {
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * Special: by larger total number of color bits
+ * ...
+ * for YUV color buffers, this returns the integer value with
+ * respect to the enumeration provided for EGL_YUV_PLANE_BPP_EXT
+ *
+ * and:
+ *
+ * EGL_BUFFER_SIZE gives the total of the color component bits of
+ * the color buffer for EGL_RGB_BUFFER or for EGL_LUMINANCE_BUFFER.
+ * ...
+ * When EGL_COLOR_BUFFER_TYPE is of type EGL_YUV_BUFFER_EXT,
+ * this will reflect the enumeration provided as an integer)
+ * for EGL_YUV_PLANE_BPP_EXT, giving a value of 0, 8 or 10
+ */
+ if (criteria->BufferSize > 0) {
+ val1 = conf1->BufferSize;
+ val2 = conf2->BufferSize;
+ }
}
}
else {
@@ -664,6 +879,36 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
return (val1 - val2);
}
+ if (conf1->YUVOrderEXT != conf2->YUVOrderEXT)
+ {
+ const EGLint yuv_order[] = {
+ EGL_NONE,
+ EGL_YUV_ORDER_YUV_EXT,
+ EGL_YUV_ORDER_YVU_EXT,
+ EGL_YUV_ORDER_YUYV_EXT,
+ EGL_YUV_ORDER_YVYU_EXT,
+ EGL_YUV_ORDER_UYVY_EXT,
+ EGL_YUV_ORDER_VYUY_EXT,
+ EGL_YUV_ORDER_AYUV_EXT,
+ };
+
+ val1 = val2 = 0;
+ for (i = 0; i < ARRAY_SIZE(yuv_order); i++) {
+ if (yuv_order[i] == conf1->YUVOrderEXT) {
+ val1 = i;
+ break;
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(yuv_order); i++) {
+ if (yuv_order[i] == conf2->YUVOrderEXT) {
+ val2 = i;
+ break;
+ }
+ }
+ if (val1 != val2)
+ return val1 - val2;
+ }
+
/* EGL_NATIVE_VISUAL_TYPE cannot be compared here */
return (compare_id) ? (conf1->ConfigID - conf2->ConfigID) : 0;
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index dcfb11b69a0..0523c8918ef 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -88,6 +88,12 @@ struct _egl_config
EGLint FramebufferTargetAndroid;
EGLint RecordableAndroid;
EGLint ComponentType;
+ EGLint YUVOrderEXT;
+ EGLint YUVNumberOfPlanesEXT;
+ EGLint YUVSubsampleEXT;
+ EGLint YUVDepthRangeEXT;
+ EGLint YUVCSCStandardEXT;
+ EGLint YUVPlaneBPPEXT;
};
@@ -138,6 +144,12 @@ _eglOffsetOfConfig(EGLint attr)
ATTRIB_MAP(EGL_FRAMEBUFFER_TARGET_ANDROID, FramebufferTargetAndroid);
ATTRIB_MAP(EGL_RECORDABLE_ANDROID, RecordableAndroid);
ATTRIB_MAP(EGL_COLOR_COMPONENT_TYPE_EXT, ComponentType);
+ ATTRIB_MAP(EGL_YUV_ORDER_EXT, YUVOrderEXT);
+ ATTRIB_MAP(EGL_YUV_NUMBER_OF_PLANES_EXT, YUVNumberOfPlanesEXT);
+ ATTRIB_MAP(EGL_YUV_SUBSAMPLE_EXT, YUVSubsampleEXT);
+ ATTRIB_MAP(EGL_YUV_DEPTH_RANGE_EXT, YUVDepthRangeEXT);
+ ATTRIB_MAP(EGL_YUV_CSC_STANDARD_EXT, YUVCSCStandardEXT);
+ ATTRIB_MAP(EGL_YUV_PLANE_BPP_EXT, YUVPlaneBPPEXT);
#undef ATTRIB_MAP
default:
return -1;
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index b4b2a2fe22b..1b9afdb343a 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -118,6 +118,7 @@ struct _egl_extensions
EGLBoolean EXT_surface_CTA861_3_metadata;
EGLBoolean EXT_surface_SMPTE2086_metadata;
EGLBoolean EXT_swap_buffers_with_damage;
+ EGLBoolean EXT_yuv_surface;
unsigned int IMG_context_priority;
#define __EGL_CONTEXT_PRIORITY_LOW_BIT 0
--
2.17.1

View file

@ -0,0 +1,35 @@
From 94c3e87ac76f0ea4b84591a45c4853fea8ea93cf Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Fri, 2 Feb 2018 16:59:52 +0000
Subject: [PATCH 024/168] dri: add missing __DRI_IMAGE_COMPONENTS define for
EGL_TEXTURE_EXTERNAL_WL
The __DRI_IMAGE_COMPONENTS defines have been re-ordered, to make it
less likely that new defines will be added with the same values as
existing ones.
---
include/GL/internal/dri_interface.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index a62ccc1b41f..4b1b691e217 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1331,11 +1331,12 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_COMPONENTS_Y_U_V 0x3003
#define __DRI_IMAGE_COMPONENTS_Y_UV 0x3004
#define __DRI_IMAGE_COMPONENTS_Y_XUXV 0x3005
+#define __DRI_IMAGE_COMPONENTS_R 0x3006
+#define __DRI_IMAGE_COMPONENTS_RG 0x3007
#define __DRI_IMAGE_COMPONENTS_Y_UXVX 0x3008
#define __DRI_IMAGE_COMPONENTS_AYUV 0x3009
#define __DRI_IMAGE_COMPONENTS_XYUV 0x300A
-#define __DRI_IMAGE_COMPONENTS_R 0x3006
-#define __DRI_IMAGE_COMPONENTS_RG 0x3007
+#define __DRI_IMAGE_COMPONENTS_EXTERNAL 0x300B
/**
--
2.17.1

View file

@ -0,0 +1,74 @@
From 6bd619dae24da9c94b62a9f7dd68e3ff7f685761 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 11 Jan 2018 09:38:47 +0000
Subject: [PATCH 025/168] egl/wayland: expose EXT_yuv_surface support
This adds support for YUYV configs.
---
src/egl/drivers/dri2/egl_dri2.c | 1 +
src/egl/drivers/dri2/platform_wayland.c | 15 ++++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 309265dc14b..d2e7b2b7922 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -2486,6 +2486,7 @@ static const struct wl_drm_components_descriptor {
{ __DRI_IMAGE_COMPONENTS_Y_U_V, EGL_TEXTURE_Y_U_V_WL, 3 },
{ __DRI_IMAGE_COMPONENTS_Y_UV, EGL_TEXTURE_Y_UV_WL, 2 },
{ __DRI_IMAGE_COMPONENTS_Y_XUXV, EGL_TEXTURE_Y_XUXV_WL, 2 },
+ { __DRI_IMAGE_COMPONENTS_EXTERNAL, EGL_TEXTURE_EXTERNAL_WL, 1 },
};
static _EGLImage *
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 775909f6138..c3fb983c341 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -151,6 +151,13 @@ static const struct dri2_wl_visual {
{ 11, 5, 0, -1 },
{ 5, 6, 5, 0 },
},
+ {
+ "YUYV",
+ WL_DRM_FORMAT_YUYV, WL_SHM_FORMAT_YUYV,
+ __DRI_IMAGE_FORMAT_YUYV, __DRI_IMAGE_FORMAT_NONE, 32,
+ { -1, -1, -1, -1 },
+ { 0, 0, 0, 0 },
+ },
};
static int
@@ -1431,6 +1438,7 @@ dri2_wl_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
{
switch (cap) {
case DRI_LOADER_CAP_FP16:
+ case DRI_LOADER_CAP_YUV_SURFACE_IMG:
return 1;
case DRI_LOADER_CAP_RGBA_ORDERING:
return 1;
@@ -2164,6 +2172,7 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
unsigned int format_count[ARRAY_SIZE(dri2_wl_visuals)] = { 0 };
unsigned int count = 0;
+ EGLint surface_type;
bool assigned;
for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
@@ -2175,8 +2184,12 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
if (!BITSET_TEST(dri2_dpy->formats.formats_bitmap, j))
continue;
+ surface_type = EGL_WINDOW_BIT;
+ if (dri2_wl_visuals[j].wl_drm_format != WL_DRM_FORMAT_YUYV)
+ surface_type |= EGL_PBUFFER_BIT;
+
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
- count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
+ count + 1, surface_type, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
if (dri2_conf) {
if (dri2_conf->base.ConfigID == count + 1)
count++;
--
2.17.1

View file

@ -0,0 +1,134 @@
From 4f30b27325e00d237f9f6bcd852033cb7ad0981d Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 30 Aug 2018 13:48:53 +0100
Subject: [PATCH 026/168] gbm: add some new GBM formats
GBM_FORMAT_ARGB4444
GBM_FORMAT_BGR888
GBM_FORMAT_AXBXGXRX106106106106
GBM_FORMAT_YUYV
GBM_FORMAT_YVU444_PACK10_IMG
---
include/GL/internal/dri_interface.h | 1 +
src/egl/drivers/dri2/egl_dri2.c | 1 +
src/gbm/backends/dri/gbm_dri.c | 21 +++++++++++++++++++++
src/gbm/main/gbm.c | 1 +
src/gbm/main/gbm.h | 8 ++++++++
5 files changed, 32 insertions(+)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 4b1b691e217..75ced1b9660 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1279,6 +1279,7 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FORMAT_YV12 0x101f
#define __DRI_IMAGE_FORMAT_YVYU 0x1020
#define __DRI_IMAGE_FORMAT_VYUY 0x1021
+#define __DRI_IMAGE_FORMAT_AXBXGXRX106106106106 0x1022
#define __DRI_IMAGE_USE_SHARE 0x0001
#define __DRI_IMAGE_USE_SCANOUT 0x0002
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index d2e7b2b7922..5cfce95aa42 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -2884,6 +2884,7 @@ dri2_num_fourcc_format_planes(EGLint format)
case DRM_FORMAT_XBGR16161616:
case DRM_FORMAT_XBGR16161616F:
case DRM_FORMAT_ABGR16161616F:
+ case DRM_FORMAT_AXBXGXRX106106106106:
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index 53edc1928d8..5b18bdcccbc 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -564,11 +564,21 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
{ 10, 5, 0, 11 },
{ 5, 5, 5, 1 },
},
+ {
+ GBM_FORMAT_ARGB4444, __DRI_IMAGE_FORMAT_ARGB4444,
+ { 8, 4, 0, 12 },
+ { 4, 4, 4, 4 },
+ },
{
GBM_FORMAT_RGB565, __DRI_IMAGE_FORMAT_RGB565,
{ 11, 5, 0, -1 },
{ 5, 6, 5, 0 },
},
+ {
+ GBM_FORMAT_BGR888, __DRI_IMAGE_FORMAT_BGR888,
+ { 0, 8, 16, -1 },
+ { 8, 8, 8, 0 },
+ },
{
GBM_FORMAT_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888,
{ 16, 8, 0, -1 },
@@ -619,6 +629,11 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
{ 0, 16, 32, 48 },
{ 16, 16, 16, 16 },
},
+ {
+ GBM_FORMAT_AXBXGXRX106106106106, __DRI_IMAGE_FORMAT_AXBXGXRX106106106106,
+ { 6, 22, 38, 54 },
+ { 10, 10, 10, 10 },
+ },
{
GBM_FORMAT_XBGR16161616F, __DRI_IMAGE_FORMAT_XBGR16161616F,
{ 0, 16, 32, -1 },
@@ -631,6 +646,12 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
{ 16, 16, 16, 16 },
true,
},
+ {
+ GBM_FORMAT_YUYV, __DRI_IMAGE_FORMAT_YUYV,
+ },
+ {
+ GBM_FORMAT_YVU444_PACK10_IMG, __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG,
+ },
};
static int
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
index 27e9f5bcd03..1b14320ba76 100644
--- a/src/gbm/main/gbm.c
+++ b/src/gbm/main/gbm.c
@@ -277,6 +277,7 @@ gbm_bo_get_bpp(struct gbm_bo *bo)
case GBM_FORMAT_ABGR16161616:
case GBM_FORMAT_XBGR16161616F:
case GBM_FORMAT_ABGR16161616F:
+ case GBM_FORMAT_AXBXGXRX106106106106:
return 64;
}
}
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
index 207b6cf9d74..067d36f16fd 100644
--- a/src/gbm/main/gbm.h
+++ b/src/gbm/main/gbm.h
@@ -171,6 +171,12 @@ enum gbm_bo_format {
#define GBM_FORMAT_ABGR16161616F __gbm_fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */
+/*
+ * RGBA format with 10-bit components packed in 64-bit per pixel, with 6 bits
+ * of unused padding per component:
+ */
+#define GBM_FORMAT_AXBXGXRX106106106106 __gbm_fourcc_code('A', 'B', '1', '0') /* [63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian */
+
/* packed YCbCr */
#define GBM_FORMAT_YUYV __gbm_fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
#define GBM_FORMAT_YVYU __gbm_fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
@@ -179,6 +185,8 @@ enum gbm_bo_format {
#define GBM_FORMAT_AYUV __gbm_fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
+#define GBM_FORMAT_YVU444_PACK10_IMG __gbm_fourcc_code('I', 'M', 'G', '2') /* [31:0] unused:Y:Cr:Cb 2:10:10:10 little endian */
+
/*
* 2 plane YCbCr
* index 0 = Y plane, [7:0] Y
--
2.17.1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,205 @@
From cb9b76162c0d7ca14523b01e803c6d40cb354a91 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 29 Jan 2019 14:36:25 +0000
Subject: [PATCH 028/168] egl: add support for EXT_image_gl_colorspace
---
src/egl/drivers/dri2/egl_dri2.c | 52 +++++++++++++++++++++++++++++++--
src/egl/main/eglapi.c | 1 +
src/egl/main/egldisplay.h | 1 +
src/egl/main/eglimage.c | 14 +++++++++
src/egl/main/eglimage.h | 3 ++
5 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 6337cb23aa4..4e39f2e7bdc 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1109,6 +1109,9 @@ dri2_setup_screen(_EGLDisplay *disp)
dri2_dpy->image->createImageFromBuffer) {
disp->Extensions.IMG_cl_image = EGL_TRUE;
}
+
+ if (disp->Extensions.KHR_gl_colorspace)
+ disp->Extensions.EXT_image_gl_colorspace = EGL_TRUE;
}
if (dri2_dpy->flush_control)
@@ -2516,6 +2519,11 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
if (!_eglParseImageAttribList(&attrs, disp, attr_list))
return NULL;
+ if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
+ _eglError(EGL_BAD_MATCH, "unsupported colorspace");
+ return NULL;
+ }
+
plane = attrs.PlaneWL;
f = buffer->driver_format;
if (plane < 0 || plane >= f->nplanes) {
@@ -2592,6 +2600,11 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
if (!_eglParseImageAttribList(&attrs, disp, attr_list))
return EGL_NO_IMAGE_KHR;
+ if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
+ _eglError(EGL_BAD_MATCH, "unsupported colorspace");
+ return EGL_NO_IMAGE_KHR;
+ }
+
switch (target) {
case EGL_GL_TEXTURE_2D_KHR:
if (!disp->Extensions.KHR_gl_texture_2D_image) {
@@ -2748,6 +2761,11 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
+ if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
+ _eglError(EGL_BAD_MATCH, "unsupported colorspace");
+ return NULL;
+ }
+
switch (attrs.DRMBufferFormatMESA) {
case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
format = __DRI_IMAGE_FORMAT_ARGB8888;
@@ -2933,6 +2951,23 @@ dri2_num_fourcc_format_planes(EGLint format)
}
}
+static int
+dri2_get_srgb_fourcc(int drm_fourcc)
+{
+ switch (drm_fourcc) {
+ case DRM_FORMAT_ARGB8888:
+ return __DRI_IMAGE_FOURCC_SARGB8888;
+ case DRM_FORMAT_ABGR8888:
+ return __DRI_IMAGE_FOURCC_SABGR8888;
+ case DRM_FORMAT_BGR888:
+ return __DRI_IMAGE_FOURCC_SBGR888;
+ default:
+ _eglLog(_EGL_DEBUG, "%s: no matching sRGB FourCC for %#x",
+ __func__, drm_fourcc);
+ return 0;
+ }
+}
+
/* Returns the total number of file descriptors. Zero indicates an error. */
static unsigned
dri2_check_dma_buf_format(const _EGLImageAttribs *attrs)
@@ -3090,6 +3125,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
int fds[DMA_BUF_MAX_PLANES];
int pitches[DMA_BUF_MAX_PLANES];
int offsets[DMA_BUF_MAX_PLANES];
+ int fourcc;
uint64_t modifier;
bool has_modifier = false;
unsigned error;
@@ -3116,6 +3152,18 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
if (!num_fds)
return NULL;
+ if (attrs.GLColorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
+ fourcc = dri2_get_srgb_fourcc(attrs.DMABufFourCC.Value);
+ if (fourcc == 0) {
+ _eglError(EGL_BAD_MATCH, "unsupported colorspace");
+ return NULL;
+ }
+ } else {
+ assert(attrs.GLColorspace == EGL_GL_COLORSPACE_LINEAR_KHR ||
+ attrs.GLColorspace == EGL_GL_COLORSPACE_DEFAULT_EXT);
+ fourcc = attrs.DMABufFourCC.Value;
+ }
+
for (unsigned i = 0; i < num_fds; ++i) {
fds[i] = attrs.DMABufPlaneFds[i].Value;
pitches[i] = attrs.DMABufPlanePitches[i].Value;
@@ -3160,7 +3208,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
}
dri_image =
dri2_dpy->image->createImageFromDmaBufs2(dri2_dpy->dri_screen,
- attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
+ attrs.Width, attrs.Height, fourcc,
modifier, fds, num_fds, pitches, offsets,
attrs.DMABufYuvColorSpaceHint.Value,
attrs.DMABufSampleRangeHint.Value,
@@ -3172,7 +3220,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
else {
dri_image =
dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
- attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
+ attrs.Width, attrs.Height, fourcc,
fds, num_fds, pitches, offsets,
attrs.DMABufYuvColorSpaceHint.Value,
attrs.DMABufSampleRangeHint.Value,
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index f8380e139f5..b5064a34c67 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -564,6 +564,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
_EGL_CHECK_EXTENSION(EXT_protected_content);
+ _EGL_CHECK_EXTENSION(EXT_image_gl_colorspace);
_EGL_CHECK_EXTENSION(EXT_protected_surface);
_EGL_CHECK_EXTENSION(EXT_present_opaque);
_EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index cedf3887c9d..4b16fb5fd02 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -112,6 +112,7 @@ struct _egl_extensions
EGLBoolean EXT_create_context_robustness;
EGLBoolean EXT_image_dma_buf_import;
EGLBoolean EXT_image_dma_buf_import_modifiers;
+ EGLBoolean EXT_image_gl_colorspace;
EGLBoolean EXT_pixel_format_float;
EGLBoolean EXT_protected_content;
EGLBoolean EXT_protected_surface;
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index 997855f48c0..1011b663b72 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -46,6 +46,18 @@ _eglParseKHRImageAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
attrs->ImagePreserved = val;
break;
+ case EGL_GL_COLORSPACE_KHR:
+ if (!disp->Extensions.EXT_image_gl_colorspace)
+ return EGL_BAD_PARAMETER;
+
+ if (val != EGL_GL_COLORSPACE_SRGB_KHR &&
+ val != EGL_GL_COLORSPACE_LINEAR_KHR &&
+ val != EGL_GL_COLORSPACE_DEFAULT_EXT)
+ return EGL_BAD_PARAMETER;
+
+ attrs->GLColorspace = val;
+ break;
+
case EGL_GL_TEXTURE_LEVEL_KHR:
if (!disp->Extensions.KHR_gl_texture_2D_image)
return EGL_BAD_PARAMETER;
@@ -286,6 +298,8 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *disp,
memset(attrs, 0, sizeof(*attrs));
+ attrs->GLColorspace = EGL_GL_COLORSPACE_DEFAULT_EXT;
+
if (!attrib_list)
return EGL_TRUE;
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index 02ad3b8ef10..003955d2b9b 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -80,6 +80,9 @@ struct _egl_image_attribs
/* EGL_EXT_protected_content || EGL_EXT_protected_surface */
EGLBoolean ProtectedContent;
+
+ /* EGL_EXT_image_gl_colorspace */
+ EGLint GLColorspace;
};
/**
--
2.17.1

View file

@ -0,0 +1,35 @@
From a306c154e036cd8d19bc73e93f03e93c2dcc5d81 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 24 Jun 2019 09:35:39 +0100
Subject: [PATCH 029/168] meson: force C++ 2011 for "thread_local"
For some combinations of Meson and the GNU C++ compiler, Meson does
not add '-std=c++11' to the command line arguments, resulting in
compilation errors, due to the use of the "thread_local" keyword (a
C++ 2011 feature). If the C++ compiler doesn't understand the
"thread_local" keyword by default, add '-std=c++11' to the compiler
command line arguments.
---
meson.build | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/meson.build b/meson.build
index 9fb6dd81d26..3bdbb622b42 100644
--- a/meson.build
+++ b/meson.build
@@ -41,6 +41,12 @@ endif
cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
+if not cpp.compiles('thread_local int x = 0;', name : 'thread_local')
+ if cpp.has_argument('-std=c++11')
+ add_project_arguments('-std=c++11', language : 'cpp')
+ endif
+endif
+
null_dep = dependency('', required : false)
if get_option('layout') != 'mirror'
--
2.17.1

View file

@ -0,0 +1,787 @@
From 97d20fbb86135061563ad4c33848a24af719b1b9 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 19 Jun 2019 16:36:06 +0100
Subject: [PATCH 030/168] dri2: add support for swap intervals other than 1
Before this change, the swap interval was fixed at 1, with page flips
scheduled on the next vblank. This change allows any swap interval
between 0 and 10 to be set.
An additional thread is created, so as not to rely on the application
polling for previously scheduled drm events (be it a flip or a vblank).
Instead, each call to swap buffers made by the application will be
queued, and consumed asynchronously by the additional thread. This
ensures that drm events will be handled as soon as possible,
regardless of the timing of subsequent calls to swap buffers.
Change-Id: If7c0495df7ddfaa08583a14f820c46e1b97da788
Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
---
src/egl/drivers/dri2/egl_dri2.h | 42 ++-
src/egl/drivers/dri2/platform_null.c | 541 +++++++++++++++++++++++----
2 files changed, 506 insertions(+), 77 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 89c48905c95..4baff09e80b 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -337,6 +337,25 @@ struct dri2_egl_context
__DRIcontext *dri_context;
};
+#define DRI2_SURFACE_NUM_COLOR_BUFFERS 4
+
+#ifdef HAVE_NULL_PLATFORM
+struct swap_queue_elem
+{
+ uint32_t swap_interval;
+ uint32_t back_id;
+ uint32_t fb_id;
+};
+
+enum {
+ SWAP_IDLE,
+ SWAP_FLIP,
+ SWAP_VBLANK,
+ SWAP_POLL,
+ SWAP_ERROR,
+};
+#endif
+
struct dri2_egl_surface
{
_EGLSurface base;
@@ -377,6 +396,19 @@ struct dri2_egl_surface
struct gbm_dri_surface *gbm_surf;
#endif
+#if defined(HAVE_NULL_PLATFORM)
+ /*
+ * Protects swap_queue_idx_head, swap_queue_idx_tail and
+ * color_buffers.locked.
+ */
+ pthread_mutex_t mutex;
+ pthread_cond_t swap_queue_cond;
+ pthread_cond_t swap_unlock_buffer_cond;
+ int swap_queue_idx_head;
+ int swap_queue_idx_tail;
+ pthread_t swap_queue_processor;
+#endif
+
/* EGL-owned buffers */
__DRIbuffer *local_buffers[__DRI_BUFFER_COUNT];
@@ -403,7 +435,7 @@ struct dri2_egl_surface
#endif
bool locked;
int age;
- } color_buffers[4], *back, *current;
+ } color_buffers[DRI2_SURFACE_NUM_COLOR_BUFFERS], *back, *current;
#endif
#ifdef HAVE_ANDROID_PLATFORM
@@ -437,7 +469,13 @@ struct dri2_egl_surface
#endif
#ifdef HAVE_NULL_PLATFORM
- uint32_t front_fb_id;
+ uint32_t front_fb_id;
+ struct swap_queue_elem swap_queue[DRI2_SURFACE_NUM_COLOR_BUFFERS];
+ struct swap_queue_elem *swap_data;
+ int swap_state;
+ bool mutex_init;
+ bool cond_init;
+ bool cond_init_unlock_buffer;
#endif
int out_fence_fd;
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index fb03ecc36fd..5b7c1ec426c 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -31,6 +31,7 @@
#include <drm_fourcc.h>
#include <fcntl.h>
#include <poll.h>
+#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -58,6 +59,17 @@ struct object_property {
uint64_t prop_value;
};
+static inline
+uint32_t get_back_buffer_id(struct dri2_egl_surface *dri2_surf)
+{
+ uintptr_t offset = ((uintptr_t) dri2_surf->back) -
+ ((uintptr_t) &dri2_surf->color_buffers[0]);
+
+ assert(dri2_surf->back && !(offset >> 32));
+
+ return (uint32_t) (offset / sizeof(dri2_surf->color_buffers[0]));
+}
+
#define object_property_set_named(output, object_type, prop_name, value) \
{ \
.object_id = (output)->object_type##_id, \
@@ -176,36 +188,6 @@ property_id_get_for_name(drmModePropertyRes **prop_res, const char *prop_name)
return 0;
}
-static void
-flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
- unsigned int tv_usec, void *user_data)
-{
- bool *plocked = user_data;
-
- if (plocked)
- *plocked = false;
-}
-
-static bool
-flip_process(int fd)
-{
- static drmEventContext evctx =
- {.version = 2, .page_flip_handler = flip_handler};
- struct pollfd pfd = {.fd = fd, .events = POLLIN};
- int ret;
-
- do {
- ret = poll(&pfd, 1, -1);
- } while (ret > 0 && pfd.revents != pfd.events);
-
- if (ret <= 0)
- return false;
-
- drmHandleEvent(fd, &evctx);
-
- return true;
-}
-
static drmModePropertyRes **
object_get_property_resources(int fd, uint32_t object_id, uint32_t object_type)
{
@@ -495,6 +477,113 @@ display_output_atomic_modeset(int fd, struct display_output *output, uint32_t fb
DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
}
+static void
+swap_enqueue_data(struct dri2_egl_surface *dri2_surf, uint32_t back_id,
+ uint32_t interval)
+{
+ struct swap_queue_elem *swap_data;
+
+ pthread_mutex_lock(&dri2_surf->mutex);
+ swap_data = &dri2_surf->swap_queue[dri2_surf->swap_queue_idx_tail];
+ swap_data->swap_interval = interval;
+ swap_data->fb_id = dri2_surf->back->fb_id;
+ swap_data->back_id = back_id;
+
+ dri2_surf->swap_queue_idx_tail++;
+ dri2_surf->swap_queue_idx_tail %= ARRAY_SIZE(dri2_surf->swap_queue);
+
+ /* Notify the swap thread there is new work to do */
+ pthread_cond_signal(&dri2_surf->swap_queue_cond);
+ pthread_mutex_unlock(&dri2_surf->mutex);
+}
+
+static void
+swap_dequeue_data_start(struct dri2_egl_surface *dri2_surf)
+{
+ pthread_mutex_lock(&dri2_surf->mutex);
+ while (dri2_surf->swap_queue_idx_head == dri2_surf->swap_queue_idx_tail)
+ pthread_cond_wait(&dri2_surf->swap_queue_cond, &dri2_surf->mutex);
+
+ dri2_surf->swap_data =
+ &dri2_surf->swap_queue[dri2_surf->swap_queue_idx_head];
+ pthread_mutex_unlock(&dri2_surf->mutex);
+}
+
+static void
+swap_dequeue_data_finish(struct dri2_egl_surface *dri2_surf)
+{
+ pthread_mutex_lock(&dri2_surf->mutex);
+
+ if (dri2_surf->current)
+ dri2_surf->current->locked = false;
+
+ dri2_surf->current =
+ &dri2_surf->color_buffers[dri2_surf->swap_data->back_id];
+ dri2_surf->swap_state = SWAP_IDLE;
+
+ dri2_surf->swap_queue_idx_head++;
+ dri2_surf->swap_queue_idx_head %= ARRAY_SIZE(dri2_surf->swap_queue);
+
+ /* Notify get_back_bo that a buffer has become available */
+ pthread_cond_signal(&dri2_surf->swap_unlock_buffer_cond);
+ pthread_mutex_unlock(&dri2_surf->mutex);
+}
+
+static void
+flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
+ unsigned int tv_usec, void *flip_data)
+{
+ struct dri2_egl_surface *dri2_surf = flip_data;
+
+ (void) tv_sec;
+ (void) tv_usec;
+ (void) sequence;
+
+ /* Ultimate queueing ops */
+ swap_dequeue_data_finish(dri2_surf);
+}
+
+static void
+vblank_handler(int fd, unsigned int sequence, unsigned int tv_sec,
+ unsigned int tv_usec, void *vblank_data)
+{
+ struct dri2_egl_surface *dri2_surf = vblank_data;
+
+ (void) tv_sec;
+ (void) tv_usec;
+ (void) sequence;
+
+ dri2_surf->swap_state = SWAP_FLIP;
+}
+
+static int
+drm_event_process(int fd)
+{
+ static drmEventContext evctx = {
+ .version = 2,
+ .page_flip_handler = flip_handler,
+ .vblank_handler = vblank_handler
+ };
+ struct pollfd pfd = {.fd = fd, .events = POLLIN};
+ int ret;
+
+ do {
+ ret = poll(&pfd, 1, -1);
+ } while (ret > 0 && pfd.revents != pfd.events);
+
+ if (ret <= 0)
+ /* Man says:
+ *
+ * On error, -1 is returned, and errno is set to indicate the
+ * cause of the error.
+ */
+ return -1;
+
+ drmHandleEvent(fd, &evctx);
+
+ return 0;
+}
+
static bool
display_output_init(int fd, struct display_output *output, bool use_atomic)
{
@@ -571,10 +660,46 @@ static int
display_output_flip(int fd, struct display_output *output, uint32_t fb_id,
uint32_t flags, void *flip_data)
{
- if (output->atomic_state)
- return display_output_atomic_flip(fd, output, fb_id, flags, flip_data);
+ int err;
+
+ do {
+ if (output->atomic_state)
+ err = display_output_atomic_flip(fd, output, fb_id, flags, flip_data);
+ else
+ err = drmModePageFlip(fd, output->crtc_id, fb_id, flags, flip_data);
+ } while (err == -EBUSY);
+
+ return err;
+}
+
+static int
+display_request_vblank(int fd, uint32_t target_frame, uint32_t flags,
+ void *vblank_data)
+{
+ drmVBlank vblank = {
+ .request = {
+ .type = flags,
+ .sequence = target_frame,
+ .signal = (unsigned long)vblank_data,
+ }
+ };
+
+ return drmWaitVBlank(fd, &vblank);
+}
+
+static int
+display_get_vblank_sequence(int fd, uint32_t *current_vblank_out)
+{
+ drmVBlank vblank = { .request = { .type = DRM_VBLANK_RELATIVE } };
+ int err;
+
+ err = drmWaitVBlank(fd, &vblank);
+ if (err)
+ return err;
- return drmModePageFlip(fd, output->crtc_id, fb_id, flags, flip_data);
+ *current_vblank_out = vblank.reply.sequence;
+
+ return 0;
}
static int
@@ -587,6 +712,213 @@ display_output_modeset(int fd, struct display_output *output, uint32_t fb_id)
&output->connector_id, 1, &output->mode);
}
+static int
+swap_idle_get_target_frame(struct dri2_egl_surface *dri2_surf,
+ uint32_t *current_vblank_out, uint32_t *target_frame_out)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ int err;
+
+ /* For intarvals bigger than 1, always update current_vblank. The
+ * spec isn't fully clear, nonetheless page 25 and 26 of the PDF of the
+ * EGL 1.5 spec say:
+ *
+ * "[the parameter interval] indicates the number of swap intervals
+ * that will elapse before a buffer swap takes place after calling
+ * eglSwapBuffers."
+ *
+ * We need to guarantee that the target frame is always ahead of the
+ * current vblank by the number of intervals set at the time swapBuffer
+ * is called. For intervals of 1 or 0, we don't need a target frame.
+ */
+ err = display_get_vblank_sequence(dri2_dpy->fd, current_vblank_out);
+ if (err)
+ return err;
+
+ assert(dri2_surf->swap_data->swap_interval > 0);
+
+ /* -1 accounts for vsync locked flip, so get a vblank one frame earlier */
+ *target_frame_out =
+ *current_vblank_out + dri2_surf->swap_data->swap_interval - 1;
+
+ return 0;
+}
+
+static int
+swap_idle_state_transition(struct dri2_egl_surface *dri2_surf,
+ uint32_t *target_frame_out)
+{
+ uint32_t current_vblank = 0;
+ uint32_t target_frame = 0;
+ int err;
+
+ /* update dri2_surf->swap_data */
+ swap_dequeue_data_start(dri2_surf);
+
+ /* update next target frame */
+ if (dri2_surf->swap_data->swap_interval > 1) {
+ err = swap_idle_get_target_frame(dri2_surf, &current_vblank,
+ &target_frame);
+ if (err) {
+ dri2_surf->swap_state = SWAP_ERROR;
+ return err;
+ }
+ }
+
+ dri2_surf->swap_state =
+ target_frame <= current_vblank ? SWAP_FLIP : SWAP_VBLANK;
+ *target_frame_out = target_frame;
+
+ return 0;
+}
+
+static int
+swap_vblank_state_transition(struct dri2_egl_surface *dri2_surf,
+ uint32_t target_frame)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ uint32_t flags = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
+ int err;
+
+ err = display_request_vblank(dri2_dpy->fd, target_frame,
+ flags, dri2_surf);
+ if (err) {
+ dri2_surf->swap_state = SWAP_ERROR;
+ return err;
+ }
+
+ dri2_surf->swap_state = SWAP_POLL;
+
+ return 0;
+}
+
+static int
+swap_flip_state_transition(struct dri2_egl_surface *dri2_surf)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ uint32_t flags;
+ int err;
+
+ flags = DRM_MODE_PAGE_FLIP_EVENT;
+ if (dri2_surf->swap_data->swap_interval == 0) {
+ assert(!dri2_dpy->atomic_enabled);
+ flags |= DRM_MODE_PAGE_FLIP_ASYNC;
+ }
+
+ err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output,
+ dri2_surf->swap_data->fb_id, flags, dri2_surf);
+ if (err) {
+ dri2_surf->swap_state = SWAP_ERROR;
+ return err;
+ }
+
+ dri2_surf->swap_state = SWAP_POLL;
+
+ return 0;
+}
+
+static int
+swap_poll_state_transition(struct dri2_egl_surface *dri2_surf)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ int err;
+
+ /* dri2_surf->swap_state is being set inside the handler */
+ err = drm_event_process(dri2_dpy->fd);
+ if (err) {
+ dri2_surf->swap_state = SWAP_ERROR;
+ return err;
+ }
+
+ return 0;
+}
+
+static inline void
+swap_error_print_message(const int state, const int err)
+{
+ switch (state) {
+ case SWAP_IDLE:
+ _eglLog(_EGL_WARNING,
+ "failed to get a target frame (err=%d)", err);
+ break;
+ case SWAP_FLIP:
+ _eglLog(_EGL_WARNING,
+ "failed to schedule a pageflip (err=%d)", err);
+ break;
+ case SWAP_VBLANK:
+ _eglLog(_EGL_WARNING,
+ "failed to request a vblank event (err=%d)", err);
+ break;
+ case SWAP_POLL:
+ _eglLog(_EGL_WARNING,
+ "failed to poll for drm event (err=%d)", err);
+ break;
+ case SWAP_ERROR:
+ _eglLog(_EGL_WARNING,
+ "failed to swap buffers, unknown swap state");
+ break;
+ default:
+ _eglLog(_EGL_FATAL,
+ "failed to swap buffers (unknown error)");
+ };
+}
+
+static void
+swap_error_state_handler(struct dri2_egl_surface *dri2_surf,
+ int state, int err)
+{
+ static bool do_log = true;
+
+ if (do_log) {
+ swap_error_print_message(state, err);
+ do_log = false;
+ }
+
+ swap_dequeue_data_finish(dri2_surf);
+}
+
+static void *
+swap_queue_processor_worker(void *data)
+{
+ struct dri2_egl_surface *dri2_surf = data;
+ int state = SWAP_IDLE, err = SWAP_ERROR;
+ uint32_t target_frame = 0;
+
+ assert(dri2_surf->swap_state == SWAP_IDLE);
+
+ while (1) {
+ switch (dri2_surf->swap_state) {
+ case SWAP_IDLE:
+ err = swap_idle_state_transition(dri2_surf, &target_frame);
+ break;
+ case SWAP_VBLANK:
+ err = swap_vblank_state_transition(dri2_surf, target_frame);
+ break;
+ case SWAP_FLIP:
+ err = swap_flip_state_transition(dri2_surf);
+ break;
+ case SWAP_POLL:
+ err = swap_poll_state_transition(dri2_surf);
+ break;
+ case SWAP_ERROR:
+ swap_error_state_handler(dri2_surf, state, err);
+ break;
+ default:
+ dri2_surf->swap_state = SWAP_ERROR;
+ break;
+ }
+
+ if (!err)
+ state = dri2_surf->swap_state;
+ }
+
+ return NULL;
+}
+
static bool
add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
uint32_t *fb_id_out)
@@ -651,15 +983,18 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
- if (!dri2_surf->back) {
+ pthread_mutex_lock(&dri2_surf->mutex);
+ while (!dri2_surf->back) {
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
if (!dri2_surf->color_buffers[i].locked) {
dri2_surf->back = &dri2_surf->color_buffers[i];
break;
}
}
+
+ /* Wait for a flip to get a buffer off the screen and unlock it */
if (!dri2_surf->back)
- return false;
+ pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond, &dri2_surf->mutex);
}
if (!dri2_surf->back->dri_image) {
@@ -671,19 +1006,23 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
__DRI_IMAGE_USE_SCANOUT,
NULL);
if (!dri2_surf->back->dri_image)
- return false;
+ goto err_unlock;
}
if (!dri2_surf->back->fb_id) {
if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->back->dri_image,
- &dri2_surf->back->fb_id)) {
- return false;
- }
+ &dri2_surf->back->fb_id))
+ goto err_unlock;
}
dri2_surf->back->locked = 1;
+ pthread_mutex_unlock(&dri2_surf->mutex);
return true;
+
+err_unlock:
+ pthread_mutex_unlock(&dri2_surf->mutex);
+ return false;
}
static _EGLSurface *
@@ -770,6 +1109,26 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config,
dri2_surf->base.Width = dri2_dpy->output.mode.hdisplay;
dri2_surf->base.Height = dri2_dpy->output.mode.vdisplay;
+ /* After the dri2_surf is created, init thread's data */
+ dri2_surf->mutex_init = !pthread_mutex_init(&dri2_surf->mutex, NULL);
+ if (!dri2_surf->mutex_init) {
+ _eglError(EGL_BAD_ALLOC, "failed to init swap thread mutex");
+ goto err_destroy_surface;
+ }
+
+ dri2_surf->cond_init = !pthread_cond_init(&dri2_surf->swap_queue_cond, NULL);
+ if (!dri2_surf->cond_init) {
+ _eglError(EGL_BAD_ALLOC, "failed to init swap queue condition");
+ goto err_destroy_surface;
+ }
+
+ dri2_surf->cond_init_unlock_buffer =
+ !pthread_cond_init(&dri2_surf->swap_unlock_buffer_cond, NULL);
+ if (!dri2_surf->cond_init_unlock_buffer) {
+ _eglError(EGL_BAD_ALLOC, "failed to init swap buffer unlock condition");
+ goto err_destroy_surface;
+ }
+
if (!get_front_bo(dri2_surf)) {
_eglError(EGL_BAD_NATIVE_WINDOW, "window get buffer");
goto err_destroy_surface;
@@ -783,6 +1142,14 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config,
}
dri2_dpy->output.in_use = true;
+ dri2_surf->swap_state = SWAP_IDLE;
+
+ err = pthread_create(&dri2_surf->swap_queue_processor, NULL,
+ swap_queue_processor_worker, dri2_surf);
+ if (err) {
+ _eglError(EGL_BAD_ALLOC, "failed to create swap thread");
+ goto err_destroy_surface;
+ }
return surf;
@@ -808,8 +1175,27 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
/* If there's a current surface then a page flip has been performed, so make
* sure we process the flip event.
*/
- if (dri2_surf->current)
- flip_process(dri2_dpy->fd);
+ if (dri2_surf->swap_queue_processor) {
+ pthread_mutex_lock(&dri2_surf->mutex);
+
+ /* Wait for any outstanding swaps to complete */
+ while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail)
+ pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond,
+ &dri2_surf->mutex);
+
+ pthread_mutex_unlock(&dri2_surf->mutex);
+ pthread_cancel(dri2_surf->swap_queue_processor);
+ pthread_join(dri2_surf->swap_queue_processor, NULL);
+ }
+
+ if (dri2_surf->cond_init)
+ pthread_cond_destroy(&dri2_surf->swap_queue_cond);
+
+ if (dri2_surf->cond_init_unlock_buffer)
+ pthread_cond_destroy(&dri2_surf->swap_unlock_buffer_cond);
+
+ if (dri2_surf->mutex_init)
+ pthread_mutex_destroy(&dri2_surf->mutex);
if (dri2_surf->front)
dri2_dpy->image->destroyImage(dri2_surf->front);
@@ -837,9 +1223,7 @@ dri2_null_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
- bool *plocked = NULL;
- uint32_t flags;
- int err;
+ uint32_t back_id;
if (dri2_surf->base.Type != EGL_WINDOW_BIT)
return EGL_TRUE;
@@ -858,34 +1242,13 @@ dri2_null_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
dri2_flush_drawable_for_swapbuffers(disp, draw);
dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
- if (dri2_surf->current) {
- /* Wait for the previous flip to happen so the next one can be queued */
- if (!flip_process(dri2_dpy->fd)) {
- _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_null_swap_buffers process");
- return EGL_FALSE;
- }
+ back_id = get_back_buffer_id(dri2_surf);
+ assert(dri2_surf->back == &dri2_surf->color_buffers[back_id]);
- plocked = &dri2_surf->current->locked;
- }
-
- flags = DRM_MODE_PAGE_FLIP_EVENT;
- if (draw->SwapInterval == 0)
- flags |= DRM_MODE_PAGE_FLIP_ASYNC;
-
- do {
- err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output,
- dri2_surf->back->fb_id, flags, plocked);
- } while (err == -EBUSY);
-
- if (err) {
- _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_null_swap_buffers flip");
- dri2_surf->back->locked = false;
- dri2_surf->back = NULL;
- return EGL_FALSE;
- }
+ swap_enqueue_data(dri2_surf, back_id, draw->SwapInterval);
+ /* This back buffer is tracked in the swap_data, safe to drop it now */
dri2_surf->back->age = 1;
- dri2_surf->current = dri2_surf->back;
dri2_surf->back = NULL;
return EGL_TRUE;
@@ -904,11 +1267,20 @@ dri2_null_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface)
return dri2_surf->back->age;
}
+static EGLBoolean
+dri2_null_swap_interval(_EGLDisplay *dpy, _EGLSurface *draw, EGLint interval)
+{
+ _eglLog(_EGL_DEBUG, "DRI2: set swap interval to %d", interval);
+ draw->SwapInterval = interval;
+ return EGL_TRUE;
+}
+
static struct dri2_egl_display_vtbl dri2_null_display_vtbl = {
.create_window_surface = dri2_null_create_window_surface,
.create_pbuffer_surface = dri2_null_create_pbuffer_surface,
.destroy_surface = dri2_null_destroy_surface,
.create_image = dri2_create_image_khr,
+ .swap_interval = dri2_null_swap_interval,
.swap_buffers = dri2_null_swap_buffers,
.query_buffer_age = dri2_null_query_buffer_age,
.get_dri_drawable = dri2_surface_get_dri_drawable,
@@ -1062,12 +1434,35 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp)
return count != 0;
}
+static void
+dri2_null_setup_swap_interval(_EGLDisplay *disp)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ const int swap_max_interval = 10; /* Arbitrary max value */
+ uint64_t value;
+ int err;
+
+ dri2_setup_swap_interval(disp, swap_max_interval);
+
+ err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
+ if (err || value == 0)
+ dri2_dpy->min_swap_interval = 1;
+
+ /**
+ * drm/atomic: Reject FLIP_ASYNC unconditionally
+ * upstream f2cbda2dba11de868759cae9c0d2bab5b8411406
+ *
+ * Only allow swap interval 0 for legacy DRM/KMS and let
+ * the app be aware that swap interval is clamped to 1.
+ */
+ if (dri2_dpy->atomic_enabled)
+ dri2_dpy->min_swap_interval = 1;
+}
EGLBoolean
dri2_initialize_null(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy;
- uint64_t value;
int err;
dri2_dpy = calloc(1, sizeof(*dri2_dpy));
@@ -1114,11 +1509,7 @@ dri2_initialize_null(_EGLDisplay *disp)
}
dri2_setup_screen(disp);
- dri2_setup_swap_interval(disp, 1);
-
- err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
- if (err || value == 0)
- dri2_dpy->min_swap_interval = 1;
+ dri2_null_setup_swap_interval(disp);
if (dri2_dpy->image->base.version < NULL_IMAGE_EXTENSION_VERSION_MIN) {
_eglError(EGL_NOT_INITIALIZED, "image extension version too old");
--
2.17.1

View file

@ -0,0 +1,215 @@
From 07ba23c3baab75df2ad7928b021cde89d8551c35 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 2 Sep 2019 09:32:01 +0100
Subject: [PATCH 031/168] null_platform: add support for explicit
synchronisation
This change adds support for the 'in' fence, the 'out' fence will
potentially be added in subsequent optimisation changes.
Explicit synchronisation KMS 'in' and 'out' properties have been first
added in Linux kernel 4.10 as an additional feature to the atomic mode
setting.
9626014258a5957ff120b3987ee72decdbe0c798 - 'in' property
beaf5af48034c9e2ebb8b2b1fb12dc4d8aeba99e - 'out' property
Unlike many other features - it doesn't have an in kernel capability
flag, so the support for it can be tested in the following way:
KMS creates an additional set of properties when the version of kernel
is new enough to support it ('in' and 'out' fence properties). When
the user-space requests all the properties from the kernel via
drmModeObjectGetProperties it is possible to determine whether the
required property is supported by the kernel or not.
The explicit synchronisation is used when available, otherwise the
implicit sync model is used instead. If explicit synchronisation is
available but 'in' fence failed to attach in KMS, the system falls
back to the implicit synchronisation model.
egl_dri2.c already creates the GPU 'out' fence that is then used by
the null_platform as KMS 'in' fence. null_platform takes owenership of
this fence fd during the swap buffers operation, at which point the
fence fd is no longer available to be used outside of null_platform.
EGL_LOG_LEVEL=debug should give some useful information in case of
explicit synchronisation failure. As mentioned above, this failure
will result in implicit synchronisation being used instead.
Change-Id: Ib9c4a0bc3ea1b21192ee37909d7580d6b7b366ec
---
src/egl/drivers/dri2/egl_dri2.h | 2 +
src/egl/drivers/dri2/platform_null.c | 77 +++++++++++++++++++++++++++-
2 files changed, 77 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 4baff09e80b..9aab57356f7 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -102,6 +102,7 @@ struct wl_buffer;
#ifdef HAVE_NULL_PLATFORM
struct display_output {
bool in_use;
+ bool in_fence_supported;
uint32_t connector_id;
drmModePropertyRes **connector_prop_res;
uint32_t crtc_id;
@@ -345,6 +346,7 @@ struct swap_queue_elem
uint32_t swap_interval;
uint32_t back_id;
uint32_t fb_id;
+ int kms_in_fence_fd;
};
enum {
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index 5b7c1ec426c..d36dc0ced2a 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -401,6 +401,9 @@ display_output_atomic_init(int fd, struct display_output *output)
if (!output->atomic_state)
goto err_destroy_mode_prop_blob;
+ if (property_id_get_for_name(plane_prop_res, "IN_FENCE_FD"))
+ output->in_fence_supported = true;
+
output->connector_prop_res = connector_prop_res;
output->crtc_prop_res = crtc_prop_res;
output->plane_prop_res = plane_prop_res;
@@ -418,6 +421,53 @@ err_free_connector_prop_res:
return false;
}
+static void
+display_output_atomic_add_in_fence(struct display_output *output,
+ int kms_in_fence_fd)
+{
+ const struct object_property obj_sync_props[] = {
+ object_property_set_named(output, plane, "IN_FENCE_FD", kms_in_fence_fd),
+ };
+ int err;
+
+ /* Explicit synchronisation is not being used */
+ if (kms_in_fence_fd < 0)
+ return;
+
+ err = atomic_state_add_object_properties(output->atomic_state,
+ obj_sync_props,
+ ARRAY_SIZE(obj_sync_props));
+ if (err)
+ _eglLog(_EGL_DEBUG, "%s: failed to add props ERR = %d", __func__, err);
+}
+
+static void
+atomic_claim_in_fence_fd(struct dri2_egl_surface *dri2_surf,
+ struct swap_queue_elem *swap_data)
+{
+ /* Explicit synchronisation is not being used */
+ if (!dri2_surf->enable_out_fence)
+ return;
+
+ if (dri2_surf->out_fence_fd < 0) {
+ _eglLog(_EGL_DEBUG, "%s: missing 'in' fence", __func__);
+ return;
+ }
+
+ /* Take ownership of the fd */
+ swap_data->kms_in_fence_fd = dri2_surf->out_fence_fd;
+ dri2_surf->out_fence_fd = -1;
+}
+
+static void
+atomic_relinquish_in_fence_fd(struct dri2_egl_surface *dri2_surf,
+ struct swap_queue_elem *swap_data)
+{
+ /* KMS is now in control of the fence (post drmModeAtomicCommit) */
+ close(swap_data->kms_in_fence_fd);
+ swap_data->kms_in_fence_fd = -1;
+}
+
static int
display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id,
uint32_t flags, void *flip_data)
@@ -425,6 +475,8 @@ display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id
const struct object_property obj_props[] = {
object_property_set_named(output, plane, "FB_ID", fb_id),
};
+ struct dri2_egl_surface *dri2_surf = flip_data;
+ struct swap_queue_elem *swap_data = dri2_surf->swap_data;
int err;
/* Reset atomic state */
@@ -435,13 +487,19 @@ display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id
if (err)
return err;
+ display_output_atomic_add_in_fence(output, swap_data->kms_in_fence_fd);
+
/*
* Don't block - like drmModePageFlip, drmModeAtomicCommit will return
* -EBUSY if the commit can't be queued in the kernel.
*/
flags |= DRM_MODE_ATOMIC_NONBLOCK;
- return drmModeAtomicCommit(fd, output->atomic_state, flags, flip_data);
+ err = drmModeAtomicCommit(fd, output->atomic_state, flags, flip_data);
+
+ atomic_relinquish_in_fence_fd(dri2_surf, swap_data);
+
+ return err;
}
static int
@@ -489,6 +547,8 @@ swap_enqueue_data(struct dri2_egl_surface *dri2_surf, uint32_t back_id,
swap_data->fb_id = dri2_surf->back->fb_id;
swap_data->back_id = back_id;
+ atomic_claim_in_fence_fd(dri2_surf, swap_data);
+
dri2_surf->swap_queue_idx_tail++;
dri2_surf->swap_queue_idx_tail %= ARRAY_SIZE(dri2_surf->swap_queue);
@@ -1025,11 +1085,21 @@ err_unlock:
return false;
}
+static void surface_swap_queue_init(struct dri2_egl_surface *dri2_surf)
+{
+ struct swap_queue_elem *swap_queue = &dri2_surf->swap_queue[0];
+ const int num_el = ARRAY_SIZE(dri2_surf->swap_queue);
+
+ for (int i = 0; i < num_el; i++)
+ swap_queue[i].kms_in_fence_fd = -1;
+}
+
static _EGLSurface *
create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct display_output *output = &dri2_dpy->output;
struct dri2_egl_config *dri2_config = dri2_egl_config(config);
struct dri2_egl_surface *dri2_surf;
const __DRIconfig *dri_config;
@@ -1043,7 +1113,8 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
}
surf = &dri2_surf->base;
- if (!dri2_init_surface(surf, disp, type, config, attrib_list, false, NULL))
+ if (!dri2_init_surface(surf, disp, type, config, attrib_list,
+ output->in_fence_supported, NULL))
goto err_free_surface;
dri_config = dri2_get_dri_config(dri2_config, type,
@@ -1066,6 +1137,8 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
dri2_surf->format = dri2_null_formats[format_idx].dri_image_format;
+ surface_swap_queue_init(dri2_surf);
+
return surf;
err_free_surface:
--
2.17.1

View file

@ -0,0 +1,384 @@
From 08c3f25175eeb21450f1d5e61a0b66c7714bc8a7 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 26 Sep 2019 13:32:15 +0100
Subject: [PATCH 032/168] egl/null: add support for DRM image format modifiers
This change introduces support for image modifiers to platform_null. In
order for it to create an image with modifiers, it relies on libdrm to
iterate all formats with associated modifiers supported by the display
for the primary drm plane in use.
drmModeFormatModifierBlobIterNext() is added to the DRM api in a different
change and it is not upstream at present.
Internal notes:
[1] IN_FORMATS blobs are available since kernel 4.14:
- db1689aa61bd1efb5ce9b896e7aa860a85b7f1b6
- https://patchwork.freedesktop.org/patch/168543
[2] the dri image->base.version threshold is 14.
- Unlike for platform_wayland, where no details were found regarding
why it's using 15
- dri_interface.h makes createImageWithModifiers available since
version 14
- dri/gbm_dri.c as an example checks for minimum version 14.
Change-Id: I0f7b030f6e1943690692674bf18daabfc153208a
Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
---
src/egl/drivers/dri2/egl_dri2.h | 3 +
src/egl/drivers/dri2/platform_null.c | 221 +++++++++++++++++++++++----
2 files changed, 198 insertions(+), 26 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 9aab57356f7..ee458fdbf61 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -113,6 +113,8 @@ struct display_output {
uint32_t mode_blob_id;
unsigned formats;
drmModeAtomicReq *atomic_state;
+ uint32_t in_formats_id;
+ struct u_vector modifiers;
};
#endif
@@ -319,6 +321,7 @@ struct dri2_egl_display
#ifdef HAVE_NULL_PLATFORM
bool atomic_enabled;
+ bool in_formats_enabled;
struct display_output output;
#endif
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index d36dc0ced2a..2c79199da26 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -40,6 +40,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <util/u_vector.h>
#include <xf86drm.h>
#include "egl_dri2.h"
@@ -156,6 +157,18 @@ format_idx_get_from_drm_format(uint32_t drm_format)
return -1;
}
+static inline uint32_t
+blob_id_from_property_value(uint64_t prop_value)
+{
+ /* The KMS properties documetation, 01.org/linuxgraphics, says:
+ *
+ * For all property types except blob properties the value is a 64-bit
+ * unsigned integer.
+ */
+ assert(!(prop_value >> 32));
+ return (uint32_t) prop_value;
+}
+
static int
atomic_state_add_object_properties(drmModeAtomicReq *atomic_state,
const struct object_property *props,
@@ -645,7 +658,66 @@ drm_event_process(int fd)
}
static bool
-display_output_init(int fd, struct display_output *output, bool use_atomic)
+plane_init_in_formats(int fd, drmModePlane *plane, struct u_vector *modifiers,
+ uint32_t *in_formats_id_out, unsigned *formats_out)
+{
+ uint32_t blob_id, prev_fmt = DRM_FORMAT_INVALID, count_formats = 0;
+ drmModeFormatModifierIterator drm_iter = {0};
+ drmModePropertyBlobRes *blob;
+ uint64_t prop_value;
+ int idx, err;
+
+ assert(plane && in_formats_id_out && formats_out);
+
+ err = !object_property_value_for_name(fd, plane->plane_id,
+ DRM_MODE_OBJECT_PLANE,
+ "IN_FORMATS", &prop_value);
+ if (err)
+ return false;
+
+ blob_id = blob_id_from_property_value(prop_value);
+ blob = drmModeGetPropertyBlob(fd, blob_id);
+
+ while (drmModeFormatModifierBlobIterNext(blob, &drm_iter)) {
+ if (drm_iter.fmt != prev_fmt) {
+ prev_fmt = drm_iter.fmt;
+ count_formats++;
+
+ idx = format_idx_get_from_drm_format(drm_iter.fmt);
+ if (idx < 0)
+ continue;
+
+ *formats_out |= (1 << idx);
+ }
+ }
+
+ drmModeFreePropertyBlob(blob);
+
+ if (!count_formats) {
+ /* None of the formats in the IN_FORMATS blob has associated modifiers */
+ _eglLog(_EGL_WARNING, "no format-modifiers found in IN_FORMATS");
+ return false;
+ }
+
+ if (plane->count_formats != count_formats)
+ /* Only some of the formats in the IN_FORMATS blob have associated modifiers,
+ * try to use this subset.
+ */
+ _eglLog(_EGL_WARNING, "discarding formats without modifiers");
+
+ /* Allocate space for modifiers, if ENOMEM fallback to plane formats */
+ if (!u_vector_init(modifiers, sizeof(uint64_t), 64)) {
+ _eglLog(_EGL_WARNING, "failed to allocate modifiers");
+ return false;
+ }
+
+ *in_formats_id_out = blob_id;
+ return true;
+}
+
+static bool
+display_output_init(int fd, struct display_output *output, bool use_atomic,
+ bool prefer_in_formats, bool *in_formats_enabled_out)
{
drmModeRes *resources;
drmModeConnector *connector;
@@ -674,16 +746,34 @@ display_output_init(int fd, struct display_output *output, bool use_atomic)
goto err_free_plane;
output->mode = connector->modes[mode_idx];
- /* Record the display supported formats */
- for (unsigned i = 0; i < plane->count_formats; i++) {
- int format_idx;
+ assert(in_formats_enabled_out && !(*in_formats_enabled_out));
- format_idx = format_idx_get_from_drm_format(plane->formats[i]);
- if (format_idx == -1)
- continue;
+ /* Track display supported formats. Look them up from IN_FORMATS blobs
+ * if they are available, otherwise use plane formats.
+ */
+ if (prefer_in_formats)
+ *in_formats_enabled_out = plane_init_in_formats(fd, plane,
+ &output->modifiers,
+ &output->in_formats_id,
+ &output->formats);
- output->formats |= (1 << format_idx);
+ if (!*in_formats_enabled_out) {
+ _eglLog(_EGL_WARNING, "fallback to plane formats");
+
+ for (unsigned i = 0; i < plane->count_formats; i++) {
+ int format_idx;
+
+ format_idx = format_idx_get_from_drm_format(plane->formats[i]);
+ if (format_idx == -1)
+ continue;
+
+ output->formats |= (1 << format_idx);
+ }
}
+
+ /* At this point we can only shut down if the look up failed and
+ * it is safe to pass NULL to drmModeFreeFormats().
+ */
if (!output->formats)
goto err_free_plane;
@@ -983,10 +1073,12 @@ static bool
add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
uint32_t *fb_id_out)
{
+ uint64_t modifiers[4] = {0};
uint32_t handles[4] = {0};
uint32_t pitches[4] = {0};
uint32_t offsets[4] = {0};
- int handle, stride, width, height, format;
+ uint32_t flags = 0;
+ int handle, stride, width, height, format, l_mod, h_mod;
int format_idx;
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HANDLE, &handle);
@@ -1001,9 +1093,47 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
format_idx = format_idx_get_from_dri_image_format(format);
assert(format_idx != -1);
- return !drmModeAddFB2(dri2_dpy->fd, width, height,
- dri2_null_formats[format_idx].drm_format,
- handles, pitches, offsets, fb_id_out, 0);
+ if (dri2_dpy->in_formats_enabled) {
+ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, &h_mod);
+ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, &l_mod);
+
+ modifiers[0] = combine_u32_into_u64((uint32_t) h_mod, (uint32_t) l_mod);
+ flags |= DRM_MODE_FB_MODIFIERS;
+ }
+
+ return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height,
+ dri2_null_formats[format_idx].drm_format,
+ handles, pitches, offsets, modifiers,
+ fb_id_out, flags);
+}
+
+static __DRIimage *
+create_image(struct dri2_egl_surface *dri2_surf, uint32_t flags)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ uint32_t count_modifiers;
+ uint64_t *modifiers;
+
+ if (dri2_dpy->in_formats_enabled) {
+ count_modifiers = u_vector_length(&dri2_dpy->output.modifiers);
+ modifiers = u_vector_tail(&dri2_dpy->output.modifiers);
+
+ return dri2_dpy->image->createImageWithModifiers(dri2_dpy->dri_screen,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ dri2_surf->format,
+ modifiers,
+ count_modifiers,
+ NULL);
+ }
+
+ return dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ dri2_surf->format,
+ flags,
+ NULL);
}
static bool
@@ -1016,12 +1146,7 @@ get_front_bo(struct dri2_egl_surface *dri2_surf)
if (dri2_surf->base.Type == EGL_WINDOW_BIT)
use |= __DRI_IMAGE_USE_SCANOUT;
- dri2_surf->front = dri2_dpy->image->createImage(dri2_dpy->dri_screen,
- dri2_surf->base.Width,
- dri2_surf->base.Height,
- dri2_surf->format,
- use,
- NULL);
+ dri2_surf->front = create_image(dri2_surf, use);
if (!dri2_surf->front)
return false;
@@ -1058,13 +1183,8 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
}
if (!dri2_surf->back->dri_image) {
- dri2_surf->back->dri_image =
- dri2_dpy->image->createImage(dri2_dpy->dri_screen,
- dri2_surf->base.Width,
- dri2_surf->base.Height,
- dri2_surf->format,
- __DRI_IMAGE_USE_SCANOUT,
- NULL);
+ dri2_surf->back->dri_image = create_image(dri2_surf,
+ __DRI_IMAGE_USE_SCANOUT);
if (!dri2_surf->back->dri_image)
goto err_unlock;
}
@@ -1094,6 +1214,30 @@ static void surface_swap_queue_init(struct dri2_egl_surface *dri2_surf)
swap_queue[i].kms_in_fence_fd = -1;
}
+static bool
+in_formats_get_modifiers(const int fd, const uint32_t in_formats_id,
+ const int drm_format, struct u_vector *modifiers)
+{
+ drmModeFormatModifierIterator drm_iter = {0};
+ drmModePropertyBlobRes *blob;
+ uint64_t *mod = NULL;
+
+ blob = drmModeGetPropertyBlob(fd, in_formats_id);
+
+ while (drmModeFormatModifierBlobIterNext(blob, &drm_iter)) {
+ if (drm_iter.fmt == drm_format) {
+ assert(drm_iter.mod != DRM_FORMAT_MOD_INVALID);
+
+ mod = u_vector_add(modifiers);
+ *mod = drm_iter.mod;
+ }
+ }
+
+ drmModeFreePropertyBlob(blob);
+
+ return mod != NULL;
+}
+
static _EGLSurface *
create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
const EGLint *attrib_list)
@@ -1105,6 +1249,7 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
const __DRIconfig *dri_config;
_EGLSurface *surf;
int format_idx;
+ bool ret;
dri2_surf = calloc(1, sizeof(*dri2_surf));
if (!dri2_surf) {
@@ -1137,6 +1282,15 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
dri2_surf->format = dri2_null_formats[format_idx].dri_image_format;
+ if (dri2_dpy->in_formats_enabled) {
+ ret = in_formats_get_modifiers(dri2_dpy->fd,
+ dri2_dpy->output.in_formats_id,
+ dri2_null_formats[format_idx].drm_format,
+ &dri2_dpy->output.modifiers);
+ if (!ret)
+ goto err_free_surface;
+ }
+
surface_swap_queue_init(dri2_surf);
return surf;
@@ -1536,6 +1690,8 @@ EGLBoolean
dri2_initialize_null(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy;
+ bool prefer_in_formats = false;
+ uint64_t value;
int err;
dri2_dpy = calloc(1, sizeof(*dri2_dpy));
@@ -1589,8 +1745,19 @@ dri2_initialize_null(_EGLDisplay *disp)
goto cleanup;
}
+ err = drmGetCap(dri2_dpy->fd_dpy, DRM_CAP_ADDFB2_MODIFIERS, &value);
+ if (!err && value) {
+ /* in_formats could be supported by the platform, however not being
+ * actually enabled, i.e. in_formats init can still fail.
+ */
+ prefer_in_formats = dri2_dpy->image->base.version >= 14 &&
+ dri2_dpy->image->createImageWithModifiers;
+ }
+
if (!display_output_init(dri2_dpy->fd, &dri2_dpy->output,
- dri2_dpy->atomic_enabled)) {
+ dri2_dpy->atomic_enabled,
+ prefer_in_formats,
+ &dri2_dpy->in_formats_enabled)) {
_eglError(EGL_NOT_INITIALIZED, "failed to create output");
goto cleanup;
}
@@ -1640,4 +1807,6 @@ dri2_teardown_null(struct dri2_egl_display *dri2_dpy)
drmModeFreeProperty(dri2_dpy->output.connector_prop_res[i]);
free(dri2_dpy->output.connector_prop_res);
}
+
+ u_vector_finish(&dri2_dpy->output.modifiers);
}
--
2.17.1

View file

@ -0,0 +1,171 @@
From f78c8281278608e32defe286cacd555b818acfb8 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 10 Feb 2020 09:23:03 +0000
Subject: [PATCH 033/168] egl: query the supported ES2 context version
For OpenGL ES contexts, the EGL specification states that querying
EGL_CONTEXT_CLIENT_VERSION with eglQueryContext may return a version
that differs from that specified at context creation time. For example,
if an OpenGL ES2 context is specified at context creation time, an
OpenGL ES3 context may be created, and so "3" should be returned
when EGL_CONTEXT_CLIENT_VERSION is queried.
A new EGL driver API function has been added,
QueryContextClientVersion, that is called when the context client
version is queried, allowing EGL drivers to override the default
value (i.e. the version specified at context creation time). If the
function returns zero, the default is used.
For DRI drivers, QueryContextClientVersion returns zero for all API
contexts other than OpenGL ES2. For OpenGL ES2, the supported context
client version is queried via the Query Renderer driver extension, using
integer query __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG. If
the query isn't supported, or the query returns zero, zero is returned
to the caller.
IMG NOTE: In order to avoid potential name and value clashes, "_IMG"
has been added to the end of the new query name, this should be removed
if an attempt is made to push this patch upstream. The value of the new
query should be adjusted to be the next one in sequence, rather than the
large value it currently has.
---
include/GL/internal/dri_interface.h | 2 ++
src/egl/drivers/dri2/egl_dri2.c | 21 +++++++++++++++++++++
src/egl/drivers/haiku/egl_haiku.cpp | 9 +++++++++
src/egl/main/eglcontext.c | 14 +++++++++++++-
src/egl/main/egldriver.h | 1 +
5 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 75ced1b9660..66a60fd46ad 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1980,6 +1980,8 @@ typedef struct __DRIDriverVtableExtensionRec {
#define __DRI2_RENDERER_HAS_PROTECTED_CONTEXT 0x0020
+#define __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG 0x7001
+
typedef struct __DRI2rendererQueryExtensionRec __DRI2rendererQueryExtension;
struct __DRI2rendererQueryExtensionRec {
__DRIextension base;
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 4e39f2e7bdc..60cc81ba536 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -2034,6 +2034,26 @@ dri2_make_current(_EGLDisplay *disp, _EGLSurface *dsurf,
return EGL_TRUE;
}
+static EGLint
+dri2_query_context_client_version(_EGLDisplay *disp, _EGLContext *ctx)
+{
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ switch (dri2_ctx->base.ClientAPI) {
+ case EGL_OPENGL_ES_API:
+ switch (dri2_ctx->base.ClientMajorVersion) {
+ case 2:
+ return dri2_renderer_query_integer(dri2_dpy,
+ __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG);
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+}
+
__DRIdrawable *
dri2_surface_get_dri_drawable(_EGLSurface *surf)
{
@@ -4033,6 +4053,7 @@ const _EGLDriver _eglDriver = {
.CreateContext = dri2_create_context,
.DestroyContext = dri2_destroy_context,
.MakeCurrent = dri2_make_current,
+ .QueryContextClientVersion = dri2_query_context_client_version,
.CreateWindowSurface = dri2_create_window_surface,
.CreatePixmapSurface = dri2_create_pixmap_surface,
.CreatePbufferSurface = dri2_create_pbuffer_surface,
diff --git a/src/egl/drivers/haiku/egl_haiku.cpp b/src/egl/drivers/haiku/egl_haiku.cpp
index 18c73c9cd8b..2690a82eb75 100644
--- a/src/egl/drivers/haiku/egl_haiku.cpp
+++ b/src/egl/drivers/haiku/egl_haiku.cpp
@@ -297,6 +297,14 @@ haiku_make_current(_EGLDisplay *disp, _EGLSurface *dsurf,
}
+extern "C"
+EGLint
+haiku_dri2_query_context_client_version(_EGLDisplay *disp, _EGLContext *ctx)
+{
+ // Tell caller to use the default value.
+ return 0;
+}
+
extern "C"
EGLBoolean
haiku_swap_buffers(_EGLDisplay *disp, _EGLSurface *surf)
@@ -316,6 +324,7 @@ const _EGLDriver _eglDriver = {
.CreateContext = haiku_create_context,
.DestroyContext = haiku_destroy_context,
.MakeCurrent = haiku_make_current,
+ .QueryContextClientVersion = haiku_dri2_query_context_client_version,
.CreateWindowSurface = haiku_create_window_surface,
.CreatePixmapSurface = haiku_create_pixmap_surface,
.CreatePbufferSurface = haiku_create_pbuffer_surface,
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 63b65cc174b..51de016266a 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -35,6 +35,7 @@
#include "eglcontext.h"
#include "egldisplay.h"
#include "eglcurrent.h"
+#include "egldriver.h"
#include "eglsurface.h"
#include "egllog.h"
#include "util/macros.h"
@@ -678,6 +679,17 @@ _eglQueryContextRenderBuffer(_EGLContext *ctx)
}
+static EGLint
+_eglQueryContextClientVersion(_EGLContext *ctx)
+{
+ _EGLDisplay *disp = ctx->Resource.Display;
+ EGLint version;
+
+ version = disp->Driver->QueryContextClientVersion(disp, ctx);
+
+ return (version) ? version : ctx->ClientMajorVersion;
+}
+
EGLBoolean
_eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value)
{
@@ -698,7 +710,7 @@ _eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value)
*value = c->Config ? c->Config->ConfigID : 0;
break;
case EGL_CONTEXT_CLIENT_VERSION:
- *value = c->ClientMajorVersion;
+ *value = _eglQueryContextClientVersion(c);
break;
case EGL_CONTEXT_CLIENT_TYPE:
*value = c->ClientAPI;
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index da2281e76ba..2f4669e0e46 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -96,6 +96,7 @@ struct _egl_driver
EGLBoolean (*MakeCurrent)(_EGLDisplay *disp,
_EGLSurface *draw, _EGLSurface *read,
_EGLContext *ctx);
+ EGLint (*QueryContextClientVersion)(_EGLDisplay *disp, _EGLContext *ctx);
/* surface funcs */
_EGLSurface *(*CreateWindowSurface)(_EGLDisplay *disp, _EGLConfig *config,
--
2.17.1

View file

@ -0,0 +1,153 @@
From 77a15e42b2362e33380fe48aff48a0b07acdae75 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 11 Jun 2020 12:29:51 +0100
Subject: [PATCH 034/168] meson: allow libGL to be built without GLX
If Meson is run with option "glx" set to "null", build the
OpenGL library without GLX.
The "eglBindAPI workaround for dEQP bug" change to eglcurrent.h
(commit 2d46c91040aeb8ebad486214159c34417fbc87db) has been
modified to use a new EGL_WITH_OPENGL define, which indicates
whether OpenGL is present or not. This allows EGL to be used
with OpenGL on platforms other than X11.
---
meson.build | 10 +++++++---
meson_options.txt | 2 +-
src/egl/main/eglcurrent.h | 7 +++----
src/glx/meson.build | 20 ++++++++++++++++----
src/meson.build | 2 +-
5 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/meson.build b/meson.build
index 3bdbb622b42..3a6de3d5ce8 100644
--- a/meson.build
+++ b/meson.build
@@ -503,7 +503,7 @@ elif _egl == 'enabled'
error('EGL requires dri, haiku, or windows')
elif not with_shared_glapi
error('EGL requires shared-glapi')
- elif not ['disabled', 'dri'].contains(with_glx)
+ elif not ['disabled', 'dri', 'null'].contains(with_glx)
error('EGL requires dri, but a GLX is being built without dri')
elif host_machine.system() == 'darwin'
error('EGL is not available on MacOS')
@@ -529,6 +529,10 @@ if with_egl and not _platforms.contains(egl_native_platform)
error('-Degl-native-platform does not specify an enabled platform')
endif
+if with_egl and with_opengl and with_glx != 'disabled'
+ pre_args += '-DEGL_WITH_OPENGL'
+endif
+
if 'x11' in _platforms
_platforms += 'xcb'
endif
@@ -580,7 +584,7 @@ if not have_mtls_dialect
endif
endif
-if with_glx != 'disabled'
+if with_glx != 'disabled' and with_glx != 'null'
if not (with_platform_x11 and with_any_opengl)
error('Cannot build GLX support without X11 platform support and at least one OpenGL API')
elif with_glx == 'xlib'
@@ -638,7 +642,7 @@ if with_any_vk and (with_platform_x11 and not with_dri3)
error('Vulkan drivers require dri3 for X11 support')
endif
if with_dri
- if with_glx == 'disabled' and not with_egl and not with_gbm
+ if (with_glx == 'disabled' or with_glx == 'null') and not with_egl and not with_gbm
error('building dri drivers require at least one windowing system')
endif
endif
diff --git a/meson_options.txt b/meson_options.txt
index 6fd37bbb100..43169974bff 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -299,7 +299,7 @@ option(
'glx',
type : 'combo',
value : 'auto',
- choices : ['auto', 'disabled', 'dri', 'xlib'],
+ choices : ['auto', 'disabled', 'dri', 'xlib', 'null'],
description : 'Build support for GLX platform'
)
option(
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index c03798eaeac..5e083027da4 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -72,11 +72,10 @@ struct _egl_thread_info
static inline EGLBoolean
_eglIsApiValid(EGLenum api)
{
-#ifndef HAVE_X11_PLATFORM
- /* OpenGL is not a valid/supported API on Android */
- return api == EGL_OPENGL_ES_API;
-#else
+#ifdef EGL_WITH_OPENGL
return (api == EGL_OPENGL_ES_API || api == EGL_OPENGL_API);
+#else
+ return api == EGL_OPENGL_ES_API;
#endif
}
diff --git a/src/glx/meson.build b/src/glx/meson.build
index 20f04742894..93470d0a9e4 100644
--- a/src/glx/meson.build
+++ b/src/glx/meson.build
@@ -122,7 +122,15 @@ else
)
endif
-libglx = static_library(
+gl_lib_cargs = [
+ '-D_REENTRANT',
+]
+
+if with_glx == 'null'
+ libglx_link = [libglapi]
+ libglx_link_whole = [libglapi_static]
+else
+ libglx = static_library(
'glx',
[files_libglx, glx_generated],
include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_glapi, inc_loader],
@@ -138,13 +146,17 @@ libglx = static_library(
idep_mesautil, idep_xmlconfig,
dep_libdrm, dep_dri2proto, dep_glproto, dep_x11, dep_glvnd, dep_xxf86vm, dep_xshmfence
],
-)
+ )
+
+ libglx_link = [libglapi_static,libglapi]
+ libglx_link_whole = [libglx]
+endif
libgl = shared_library(
gl_lib_name,
[],
- link_with : [libglapi_static, libglapi],
- link_whole : libglx,
+ link_with : libglx_link,
+ link_whole : libglx_link_whole,
link_args : [ld_args_bsymbolic, ld_args_gc_sections, extra_ld_args_libgl],
dependencies : [
dep_libdrm, dep_dl, dep_m, dep_thread, dep_x11, dep_xcb_glx, dep_xcb,
diff --git a/src/meson.build b/src/meson.build
index 3c468e86a53..6500312bb29 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -128,7 +128,7 @@ endif
if with_gallium
subdir('mesa')
subdir('gallium')
- if with_glx == 'dri'
+ if with_glx == 'dri' or with_glx == 'null'
subdir('glx')
endif
# This has to be here since it requires libgallium, and subdir cannot
--
2.17.1

View file

@ -0,0 +1,38 @@
From 9671db93a033595b0805088e5ef5728cd99e18a2 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 25 Aug 2020 14:12:32 +0100
Subject: [PATCH 035/168] egl/wayland: process non-resized window movement
The dx and dy parameters to the wl_egl_window_resize function were
not being processed unless the window width or height were being
changed.
---
src/egl/drivers/dri2/platform_wayland.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index c3fb983c341..86a9305178d 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -392,6 +392,9 @@ resize_callback(struct wl_egl_window *wl_win, void *data)
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
+ dri2_surf->dx = wl_win->dx;
+ dri2_surf->dy = wl_win->dy;
+
if (dri2_surf->base.Width == wl_win->width &&
dri2_surf->base.Height == wl_win->height)
return;
@@ -1255,8 +1258,6 @@ update_buffers(struct dri2_egl_display *dri2_dpy,
dri2_surf->base.Width = dri2_surf->wl_win->width;
dri2_surf->base.Height = dri2_surf->wl_win->height;
- dri2_surf->dx = dri2_surf->wl_win->dx;
- dri2_surf->dy = dri2_surf->wl_win->dy;
}
if (dri2_surf->resized || dri2_surf->received_dmabuf_feedback) {
--
2.17.1

View file

@ -0,0 +1,372 @@
From 3922d9a05ebe661eb17dd7e4a75ca40ee2205d6a Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 10 Mar 2014 13:43:45 +0000
Subject: [PATCH 036/168] Separate EXT_framebuffer_object from ARB version
This patch separates the EXT_framebuffer_object entry points from the ARB
equivalents.
Probably not all this separation is necessary; it looks like only
BindRenderbuffer
BindFramebuffer
GetFramebufferAttachmentParameteriv
take advantage of the split.
Next time this patch is implemented, see if it can be trimmed down to
just the above functions, as it may be more upstreamable.
We may need to implement the EXT restrictions if we want to upstream.
---
src/mapi/glapi/gen/EXT_framebuffer_object.xml | 30 +++----
src/mapi/glapi/gen/static_data.py | 15 ++++
src/mesa/main/fbobject.c | 83 +++++++++++++++++++
src/mesa/main/genmipmap.c | 6 ++
4 files changed, 119 insertions(+), 15 deletions(-)
diff --git a/src/mapi/glapi/gen/EXT_framebuffer_object.xml b/src/mapi/glapi/gen/EXT_framebuffer_object.xml
index 6dd90b87971..e2dfa6b25ad 100644
--- a/src/mapi/glapi/gen/EXT_framebuffer_object.xml
+++ b/src/mapi/glapi/gen/EXT_framebuffer_object.xml
@@ -70,7 +70,7 @@
</enum>
<enum name="INVALID_FRAMEBUFFER_OPERATION_EXT" value="0x0506"/>
- <function name="IsRenderbufferEXT" alias="IsRenderbuffer">
+ <function name="IsRenderbufferEXT">
<param name="renderbuffer" type="GLuint"/>
<return type="GLboolean"/>
</function>
@@ -81,30 +81,30 @@
<glx rop="4316"/>
</function>
- <function name="DeleteRenderbuffersEXT" alias="DeleteRenderbuffers">
+ <function name="DeleteRenderbuffersEXT">
<param name="n" type="GLsizei"/>
<param name="renderbuffers" type="const GLuint *"/>
</function>
- <function name="GenRenderbuffersEXT" alias="GenRenderbuffers">
+ <function name="GenRenderbuffersEXT">
<param name="n" type="GLsizei"/>
<param name="renderbuffers" type="GLuint *"/>
</function>
- <function name="RenderbufferStorageEXT" alias="RenderbufferStorage">
+ <function name="RenderbufferStorageEXT">
<param name="target" type="GLenum"/>
<param name="internalformat" type="GLenum"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
</function>
- <function name="GetRenderbufferParameterivEXT" alias="GetRenderbufferParameteriv">
+ <function name="GetRenderbufferParameterivEXT">
<param name="target" type="GLenum"/>
<param name="pname" type="GLenum"/>
<param name="params" type="GLint *"/>
</function>
- <function name="IsFramebufferEXT" alias="IsFramebuffer">
+ <function name="IsFramebufferEXT">
<param name="framebuffer" type="GLuint"/>
<return type="GLboolean"/>
</function>
@@ -116,22 +116,22 @@
<glx rop="4319"/>
</function>
- <function name="DeleteFramebuffersEXT" alias="DeleteFramebuffers">
+ <function name="DeleteFramebuffersEXT">
<param name="n" type="GLsizei"/>
<param name="framebuffers" type="const GLuint *"/>
</function>
- <function name="GenFramebuffersEXT" alias="GenFramebuffers">
+ <function name="GenFramebuffersEXT">
<param name="n" type="GLsizei"/>
<param name="framebuffers" type="GLuint *"/>
</function>
- <function name="CheckFramebufferStatusEXT" alias="CheckFramebufferStatus">
+ <function name="CheckFramebufferStatusEXT">
<param name="target" type="GLenum"/>
<return type="GLenum"/>
</function>
- <function name="FramebufferTexture1DEXT" alias="FramebufferTexture1D">
+ <function name="FramebufferTexture1DEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="textarget" type="GLenum"/>
@@ -139,7 +139,7 @@
<param name="level" type="GLint"/>
</function>
- <function name="FramebufferTexture2DEXT" alias="FramebufferTexture2D">
+ <function name="FramebufferTexture2DEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="textarget" type="GLenum"/>
@@ -147,7 +147,7 @@
<param name="level" type="GLint"/>
</function>
- <function name="FramebufferTexture3DEXT" alias="FramebufferTexture3D">
+ <function name="FramebufferTexture3DEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="textarget" type="GLenum"/>
@@ -156,21 +156,21 @@
<param name="zoffset" type="GLint"/>
</function>
- <function name="FramebufferRenderbufferEXT" alias="FramebufferRenderbuffer">
+ <function name="FramebufferRenderbufferEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="renderbuffertarget" type="GLenum"/>
<param name="renderbuffer" type="GLuint"/>
</function>
- <function name="GetFramebufferAttachmentParameterivEXT" alias="GetFramebufferAttachmentParameteriv">
+ <function name="GetFramebufferAttachmentParameterivEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="pname" type="GLenum"/>
<param name="params" type="GLint *"/>
</function>
- <function name="GenerateMipmapEXT" alias="GenerateMipmap">
+ <function name="GenerateMipmapEXT">
<param name="target" type="GLenum"/>
</function>
</category>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index dd4a802c496..c81845d7f0c 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1717,6 +1717,21 @@ offsets = {
"FramebufferTextureMultisampleMultiviewOVR" : 1681,
"MultiDrawArraysIndirectEXT" : 1682,
"MultiDrawElementsIndirectEXT" : 1683,
+ "IsRenderbufferEXT" : 1684,
+ "DeleteRenderbuffersEXT" : 1685,
+ "GenRenderbuffersEXT" : 1686,
+ "RenderbufferStorageEXT" : 1687,
+ "GetRenderbufferParameterivEXT" : 1688,
+ "IsFramebufferEXT" : 1689,
+ "DeleteFramebuffersEXT" : 1690,
+ "GenFramebuffersEXT" : 1691,
+ "CheckFramebufferStatusEXT" : 1692,
+ "FramebufferTexture1DEXT" : 1693,
+ "FramebufferTexture2DEXT" : 1694,
+ "FramebufferTexture3DEXT" : 1695,
+ "FramebufferRenderbufferEXT" : 1696,
+ "GetFramebufferAttachmentParameterivEXT" : 1697,
+ "GenerateMipmapEXT" : 1698,
}
functions = [
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index be1d61907a4..74f6e9b3ff6 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -2168,6 +2168,11 @@ _mesa_detach_renderbuffer(struct gl_context *ctx,
return progress;
}
+GLboolean GLAPIENTRY
+_mesa_IsRenderbufferEXT(GLuint renderbuffer)
+{
+ return _mesa_IsRenderbuffer(renderbuffer);
+}
void GLAPIENTRY
_mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
@@ -2895,6 +2900,12 @@ renderbuffer_storage_target(GLenum target, GLenum internalFormat,
}
+void GLAPIENTRY
+_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
+{
+ _mesa_DeleteRenderbuffers(n, renderbuffers);
+}
+
void GLAPIENTRY
_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
{
@@ -2932,6 +2943,11 @@ _mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
st_egl_image_target_renderbuffer_storage(ctx, rb, image);
}
+void GLAPIENTRY
+_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
+{
+ _mesa_GenRenderbuffers(n, renderbuffers);
+}
/**
* Helper function for _mesa_GetRenderbufferParameteriv() and
@@ -2964,6 +2980,12 @@ _mesa_RenderbufferStorage(GLenum target, GLenum internalFormat,
NO_SAMPLES, 0, "glRenderbufferStorage");
}
+void GLAPIENTRY
+_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
+ GLsizei width, GLsizei height)
+{
+ _mesa_RenderbufferStorage(target, internalFormat, width, height);
+}
void GLAPIENTRY
_mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
@@ -3144,6 +3166,11 @@ _mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname,
"glGetNamedRenderbufferParameteriv");
}
+void GLAPIENTRY
+_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ _mesa_GetRenderbufferParameteriv(target, pname, params);
+}
void GLAPIENTRY
_mesa_GetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname,
@@ -3177,6 +3204,11 @@ _mesa_IsFramebuffer(GLuint framebuffer)
return GL_FALSE;
}
+GLboolean GLAPIENTRY
+_mesa_IsFramebufferEXT(GLuint framebuffer)
+{
+ return _mesa_IsFramebuffer(framebuffer);
+}
/**
* Check if any of the attachments of the given framebuffer are textures
@@ -3401,6 +3433,11 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
}
}
+void GLAPIENTRY
+_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
+{
+ _mesa_DeleteFramebuffers(n, framebuffers);
+}
/**
* This is the implementation for glGenFramebuffers and glCreateFramebuffers.
@@ -3447,6 +3484,11 @@ create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa)
_mesa_HashUnlockMutex(ctx->Shared->FrameBuffers);
}
+void GLAPIENTRY
+_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
+{
+ _mesa_GenFramebuffers(n, framebuffers);
+}
void GLAPIENTRY
_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
@@ -3486,6 +3528,11 @@ _mesa_check_framebuffer_status(struct gl_context *ctx,
return buffer->_Status;
}
+GLenum GLAPIENTRY
+_mesa_CheckFramebufferStatusEXT(GLenum target)
+{
+ return _mesa_CheckFramebufferStatus(target);
+}
GLenum GLAPIENTRY
_mesa_CheckFramebufferStatus_no_error(GLenum target)
@@ -4099,6 +4146,12 @@ _mesa_FramebufferTexture1D_no_error(GLenum target, GLenum attachment,
texture, level, 0);
}
+void GLAPIENTRY
+_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ _mesa_FramebufferTexture1D(target, attachment, textarget, texture, level);
+}
void GLAPIENTRY
_mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
@@ -4139,6 +4192,12 @@ _mesa_FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment,
false);
}
+void GLAPIENTRY
+_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ _mesa_FramebufferTexture2D(target, attachment, textarget, texture, level);
+}
void GLAPIENTRY
_mesa_FramebufferTexture3D_no_error(GLenum target, GLenum attachment,
@@ -4249,6 +4308,15 @@ frame_buffer_texture(GLuint framebuffer, GLenum target,
level, 0, layer, layered);
}
+void GLAPIENTRY
+_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level, GLint zoffset)
+{
+ _mesa_FramebufferTexture3D(target, attachment, textarget, texture,
+ level, zoffset);
+}
+
void GLAPIENTRY
_mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment,
GLuint texture, GLint level,
@@ -4501,6 +4569,15 @@ _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
renderbuffer, "glFramebufferRenderbuffer");
}
+void GLAPIENTRY
+_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
+ GLenum renderbufferTarget,
+ GLuint renderbuffer)
+{
+ _mesa_FramebufferRenderbuffer(target, attachment, renderbufferTarget,
+ renderbuffer);
+}
+
void GLAPIENTRY
_mesa_NamedFramebufferRenderbuffer_no_error(GLuint framebuffer,
GLenum attachment,
@@ -4902,6 +4979,12 @@ invalid_pname_enum:
return;
}
+void GLAPIENTRY
+_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
+ GLenum pname, GLint *params)
+{
+ _mesa_GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
void GLAPIENTRY
_mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
diff --git a/src/mesa/main/genmipmap.c b/src/mesa/main/genmipmap.c
index 97d0ab36a13..b30cf4f07c4 100644
--- a/src/mesa/main/genmipmap.c
+++ b/src/mesa/main/genmipmap.c
@@ -286,3 +286,9 @@ _mesa_GenerateMultiTexMipmapEXT(GLenum texunit, GLenum target)
validate_params_and_generate_mipmap(texObj,
"glGenerateMultiTexMipmapEXT");
}
+
+void GLAPIENTRY
+_mesa_GenerateMipmapEXT(GLenum target)
+{
+ _mesa_GenerateMipmap(target);
+}
--
2.17.1

View file

@ -0,0 +1,321 @@
From b355302f58881c0bd57b94e2540095c80b20fd43 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 21 Oct 2019 09:21:52 +0100
Subject: [PATCH 037/168] egl/null: add support for async flip with front
buffer rendering
This change enables the application to render into the buffer being
scanned out if the display driver doesn't support
DRM_CAP_ASYNC_PAGE_FLIP.
The egl display now tracks the DRM async flip capabilities, allowing
platform_null to always return the buffer on screen to the application
when the swap interval is set to 0, but the DRM driver doesn't support
async flip.
platform_null can be in several alternative states by the time
eglSwapInterval() is called, following is a summary of them.
1. platform_null was initialised and it has already flipped. In this
case, return to the client API a reference to the buffer on screen
2. platform_null was initialised but no back buffer was requested yet
from the client API. In this case, return a reference to the front
buffer
3. platform_null was initialised and the client API has already got
a back buffer, but no flip was scheduled. In this case, make sure
to flip and return the buffer on the screen
Note that this change also refactors the color buffers and front
buffer code. Platform null after this change has a dedicated struct
for storing front buffer DRI data and framebuffer id.
Also be noted that min_swap_interval is no longer clamped to 1 when
DRM_CAP_ASYNC_PAGE_FLIP isn't supported. This is because,
if min_swap_interval is automatically promoted to 1, Mesa EGL will de
facto prevent the application from requesting any swap interval less
than 1.
Change-Id: I3930cfcdb30bfb5358166911bcf84a78bdb4548d
Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
---
src/egl/drivers/dri2/egl_dri2.h | 8 +-
src/egl/drivers/dri2/platform_null.c | 153 +++++++++++++++++++++------
2 files changed, 129 insertions(+), 32 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index ee458fdbf61..8bef835ef16 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -322,6 +322,7 @@ struct dri2_egl_display
#ifdef HAVE_NULL_PLATFORM
bool atomic_enabled;
bool in_formats_enabled;
+ bool async_flip_enabled;
struct display_output output;
#endif
@@ -440,8 +441,12 @@ struct dri2_egl_surface
#endif
bool locked;
int age;
+#ifdef HAVE_NULL_PLATFORM
+ } color_buffers[DRI2_SURFACE_NUM_COLOR_BUFFERS], *back, *current, front_buffer;
+#else
} color_buffers[DRI2_SURFACE_NUM_COLOR_BUFFERS], *back, *current;
#endif
+#endif
#ifdef HAVE_ANDROID_PLATFORM
struct ANativeWindow *window;
@@ -474,12 +479,13 @@ struct dri2_egl_surface
#endif
#ifdef HAVE_NULL_PLATFORM
- uint32_t front_fb_id;
struct swap_queue_elem swap_queue[DRI2_SURFACE_NUM_COLOR_BUFFERS];
struct swap_queue_elem *swap_data;
int swap_state;
bool mutex_init;
bool cond_init;
+ bool front_render_enabled;
+ bool front_render_init;
bool cond_init_unlock_buffer;
#endif
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index 2c79199da26..0ce7e60030b 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -602,6 +602,15 @@ swap_dequeue_data_finish(struct dri2_egl_surface *dri2_surf)
pthread_mutex_unlock(&dri2_surf->mutex);
}
+static void
+swap_drain_queue_data(struct dri2_egl_surface *dri2_surf)
+{
+ pthread_mutex_lock(&dri2_surf->mutex);
+ while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail)
+ pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond, &dri2_surf->mutex);
+ pthread_mutex_unlock(&dri2_surf->mutex);
+}
+
static void
flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
unsigned int tv_usec, void *flip_data)
@@ -1146,15 +1155,15 @@ get_front_bo(struct dri2_egl_surface *dri2_surf)
if (dri2_surf->base.Type == EGL_WINDOW_BIT)
use |= __DRI_IMAGE_USE_SCANOUT;
- dri2_surf->front = create_image(dri2_surf, use);
- if (!dri2_surf->front)
+ dri2_surf->front_buffer.dri_image = create_image(dri2_surf, use);
+ if (!dri2_surf->front_buffer.dri_image)
return false;
if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
- if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->front,
- &dri2_surf->front_fb_id)) {
- dri2_dpy->image->destroyImage(dri2_surf->front);
- dri2_surf->front = NULL;
+ if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->front_buffer.dri_image,
+ &dri2_surf->front_buffer.fb_id)) {
+ dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image);
+ dri2_surf->front_buffer.dri_image = NULL;
return false;
}
}
@@ -1362,7 +1371,7 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config,
}
err = display_output_modeset(dri2_dpy->fd, &dri2_dpy->output,
- dri2_surf->front_fb_id);
+ dri2_surf->front_buffer.fb_id);
if (err) {
_eglError(EGL_BAD_NATIVE_WINDOW, "window set mode");
goto err_destroy_surface;
@@ -1392,6 +1401,60 @@ dri2_null_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *config,
return create_surface(disp, config, EGL_PBUFFER_BIT, attrib_list);
}
+static void
+dri2_null_init_front_buffer_render(_EGLSurface *draw)
+{
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+
+ dri2_surf->front_render_init = true;
+
+ /* Drain the queue. swap_buffer_unlock_cond signals for the last time
+ * when the last back buffer in the queue went on screen and it's being
+ * tracked as current by then.
+ */
+ swap_drain_queue_data(dri2_surf);
+
+ /* If previously flipped, take a reference to the current buffer */
+ if (dri2_surf->current) {
+ assert(dri2_surf->current->dri_image);
+ dri2_surf->back = dri2_surf->current;
+
+ for (unsigned i = 0; i < DRI2_SURFACE_NUM_COLOR_BUFFERS; i++)
+ dri2_surf->color_buffers[i].age = 0;
+
+ return;
+ }
+
+ /* If the application hasn't yet fetched a back buffer, then it's not too
+ * late to use front buffer's dri_image and fb_id.
+ */
+ if (!dri2_surf->back) {
+ assert(dri2_surf->front_buffer.dri_image);
+ dri2_surf->back = &dri2_surf->front_buffer;
+
+ /* Don't need to reset buffer age since no flip was requested yet */
+
+ return;
+ }
+
+ /* In order to initialise one color buffer for front buffer rendering,
+ * one page flip must occur.
+ */
+ swap_enqueue_data(dri2_surf, get_back_buffer_id(dri2_surf), 1);
+
+ return dri2_null_init_front_buffer_render(draw);
+}
+
+static void
+dri2_null_disable_front_buffer_render(_EGLSurface *draw)
+{
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+
+ dri2_surf->front_render_enabled = false;
+ dri2_surf->front_render_init = false;
+ dri2_surf->back = NULL;
+}
+
static EGLBoolean
dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
{
@@ -1403,14 +1466,7 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
* sure we process the flip event.
*/
if (dri2_surf->swap_queue_processor) {
- pthread_mutex_lock(&dri2_surf->mutex);
-
- /* Wait for any outstanding swaps to complete */
- while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail)
- pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond,
- &dri2_surf->mutex);
-
- pthread_mutex_unlock(&dri2_surf->mutex);
+ swap_drain_queue_data(dri2_surf);
pthread_cancel(dri2_surf->swap_queue_processor);
pthread_join(dri2_surf->swap_queue_processor, NULL);
}
@@ -1424,11 +1480,11 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
if (dri2_surf->mutex_init)
pthread_mutex_destroy(&dri2_surf->mutex);
- if (dri2_surf->front)
- dri2_dpy->image->destroyImage(dri2_surf->front);
+ if (dri2_surf->front_buffer.dri_image)
+ dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image);
- if (dri2_surf->front_fb_id)
- drmModeRmFB(dri2_dpy->fd, dri2_surf->front_fb_id);
+ if (dri2_surf->front_buffer.fb_id)
+ drmModeRmFB(dri2_dpy->fd, dri2_surf->front_buffer.fb_id);
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
if (dri2_surf->color_buffers[i].fb_id)
@@ -1455,6 +1511,16 @@ dri2_null_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
if (dri2_surf->base.Type != EGL_WINDOW_BIT)
return EGL_TRUE;
+ /* Flush and early return, no swap takes place */
+ if (dri2_surf->front_render_enabled) {
+ dri2_flush_drawable_for_swapbuffers(disp, draw);
+
+ if (!dri2_surf->front_render_init)
+ dri2_null_init_front_buffer_render(draw);
+
+ return EGL_TRUE;
+ }
+
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
if (dri2_surf->color_buffers[i].age > 0)
dri2_surf->color_buffers[i].age++;
@@ -1497,6 +1563,22 @@ dri2_null_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface)
static EGLBoolean
dri2_null_swap_interval(_EGLDisplay *dpy, _EGLSurface *draw, EGLint interval)
{
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ /* dri2_dpy tracks whether the display driver is async flip capable.
+ * If it isn't, enable front buffer rendering when swap interval
+ * 0 is passed in from the application.
+ */
+ if (!interval && !dri2_dpy->async_flip_enabled) {
+ if (!dri2_surf->front_render_enabled)
+ dri2_surf->front_render_enabled = true;
+ } else {
+ if (dri2_surf->front_render_enabled)
+ dri2_null_disable_front_buffer_render(draw);
+ }
+
_eglLog(_EGL_DEBUG, "DRI2: set swap interval to %d", interval);
draw->SwapInterval = interval;
return EGL_TRUE;
@@ -1534,7 +1616,7 @@ dri2_null_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format,
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
- buffers->front = dri2_surf->front;
+ buffers->front = dri2_surf->front_buffer.dri_image;
}
if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
@@ -1672,18 +1754,27 @@ dri2_null_setup_swap_interval(_EGLDisplay *disp)
dri2_setup_swap_interval(disp, swap_max_interval);
err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
- if (err || value == 0)
- dri2_dpy->min_swap_interval = 1;
+ if (err || value == 0) {
- /**
- * drm/atomic: Reject FLIP_ASYNC unconditionally
- * upstream f2cbda2dba11de868759cae9c0d2bab5b8411406
- *
- * Only allow swap interval 0 for legacy DRM/KMS and let
- * the app be aware that swap interval is clamped to 1.
- */
- if (dri2_dpy->atomic_enabled)
- dri2_dpy->min_swap_interval = 1;
+ /* DRM/KMS does not support async page flip. In order to support
+ * swap interval 0, use front buffer rendering.
+ */
+ _eglLog(_EGL_DEBUG,
+ "drm async flip not supported, use front buffer");
+ } else {
+
+ /* drm/atomic: Reject FLIP_ASYNC unconditionally
+ * upstream f2cbda2dba11de868759cae9c0d2bab5b8411406
+ *
+ * Legacy DRM/KMS can use DRM_MODE_PAGE_FLIP_ASYNC, for atomic
+ * drivers fallback to front buffer rendering.
+ */
+ if (dri2_dpy->atomic_enabled)
+ _eglLog(_EGL_DEBUG,
+ "async flip not supported by atomic, use front buffer");
+ else
+ dri2_dpy->async_flip_enabled = true;
+ }
}
EGLBoolean
--
2.17.1

View file

@ -0,0 +1,229 @@
From 3b52d830ed80131e7fb719a7e3c6b56005e464f1 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Fri, 21 Aug 2020 12:13:28 +0100
Subject: [PATCH 038/168] gbm: add pbuffer support
The EGL backend GLX provider for XWayland may get the EGL configs it
uses to generate the GLX ones from GBM. That platform doesn't support
pbuffers. When the client tries to match GLX configs with the DRI ones,
a mismatch in the pbuffer attributes will result in the GLX config
being rejected.
Although support for creating pbuffers has been added, this isn't
required when using the EGL backend GLX provider, as indirect GLX
isn't supported.
---
src/egl/drivers/dri2/egl_dri2.h | 3 +
src/egl/drivers/dri2/platform_drm.c | 110 +++++++++++++++++++++++++---
2 files changed, 103 insertions(+), 10 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 8bef835ef16..29f24f57a63 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -473,6 +473,9 @@ struct dri2_egl_surface
/* surfaceless and device */
__DRIimage *front;
unsigned int visual;
+#ifdef HAVE_DRM_PLATFORM
+ struct gbm_bo *front_bo;
+#endif
#ifdef HAVE_WAYLAND_PLATFORM
void *swrast_front;
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 45895a88b6c..4d08851c782 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -41,6 +41,38 @@
#include "egl_dri2.h"
#include "loader.h"
+static bool
+dri2_drm_alloc_front_image(struct dri2_egl_surface *dri2_surf)
+{
+ if (!dri2_surf->front_bo) {
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
+
+ dri2_surf->front_bo = gbm_bo_create(&dri2_dpy->gbm_dri->base,
+ surf->base.v0.width,
+ surf->base.v0.height,
+ surf->base.v0.format,
+ surf->base.v0.flags);
+ if (!dri2_surf->front_bo) {
+ _eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void
+dri2_drm_free_front_image(struct dri2_egl_surface *dri2_surf)
+{
+ if (dri2_surf->front_bo) {
+ gbm_bo_destroy(dri2_surf->front_bo);
+ dri2_surf->front_bo = NULL;
+ }
+}
+
static struct gbm_bo *
lock_front_buffer(struct gbm_surface *_surf)
{
@@ -138,8 +170,8 @@ dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy,
}
static _EGLSurface *
-dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
- void *native_surface, const EGLint *attrib_list)
+dri2_drm_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
+ void *native_surface, const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
@@ -154,11 +186,25 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
- if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf,
+ if (!dri2_init_surface(&dri2_surf->base, disp, type, conf,
attrib_list, false, native_surface))
goto cleanup_surf;
- config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ if (type == EGL_PBUFFER_BIT) {
+ struct gbm_device *gbm = disp->PlatformDisplay;
+ _EGLSurface *surf = &dri2_surf->base;
+
+ assert(!surface);
+
+ surface = gbm_surface_create(gbm, surf->Width, surf->Height,
+ conf->NativeVisualID, GBM_BO_USE_RENDERING);
+ if (!surface) {
+ _eglError(EGL_BAD_ALLOC, "Failed to allocate pbuffer GBM surface");
+ goto cleanup_surf;
+ }
+ }
+
+ config = dri2_get_dri_config(dri2_conf, type,
dri2_surf->base.GLColorspace);
if (!config) {
@@ -183,11 +229,22 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
return &dri2_surf->base;
cleanup_surf:
+ if (type == EGL_PBUFFER_BIT && surface != NULL)
+ gbm_surface_destroy(surface);
+
free(dri2_surf);
return NULL;
}
+static _EGLSurface *
+dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ void *native_surface, const EGLint *attrib_list)
+{
+ return dri2_drm_create_surface(disp, EGL_WINDOW_BIT, conf,
+ native_surface, attrib_list);
+}
+
static _EGLSurface *
dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
void *native_window, const EGLint *attrib_list)
@@ -202,6 +259,14 @@ dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
+static _EGLSurface *
+dri2_drm_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ const EGLint *attrib_list)
+{
+ return dri2_drm_create_surface(disp, EGL_PBUFFER_BIT, conf,
+ NULL, attrib_list);
+}
+
static EGLBoolean
dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
{
@@ -217,6 +282,11 @@ dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dri2_egl_surface_free_local_buffers(dri2_surf);
+ dri2_drm_free_front_image(dri2_surf);
+
+ if (surf->Type == EGL_PBUFFER_BIT)
+ gbm_surface_destroy(&dri2_surf->gbm_surf->base);
+
dri2_fini_surface(surf);
free(surf);
@@ -402,12 +472,27 @@ dri2_drm_image_get_buffers(__DRIdrawable *driDrawable,
struct dri2_egl_surface *dri2_surf = loaderPrivate;
struct gbm_dri_bo *bo;
- if (get_back_bo(dri2_surf) < 0)
- return 0;
+ buffers->image_mask = 0;
+ buffers->front = NULL;
+ buffers->back = NULL;
- bo = gbm_dri_bo(dri2_surf->back->bo);
- buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
- buffers->back = bo->image;
+ if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
+ if (!dri2_drm_alloc_front_image(dri2_surf))
+ return 0;
+
+ bo = gbm_dri_bo(dri2_surf->front_bo);
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
+ buffers->front = bo->image;
+ }
+
+ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
+ if (get_back_bo(dri2_surf) < 0)
+ return 0;
+
+ bo = gbm_dri_bo(dri2_surf->back->bo);
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+ buffers->back = bo->image;
+ }
return 1;
}
@@ -425,6 +510,9 @@ dri2_drm_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ if (dri2_surf->base.Type != EGL_WINDOW_BIT)
+ return EGL_TRUE;
+
if (!dri2_dpy->flush) {
dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
return EGL_TRUE;
@@ -648,7 +736,8 @@ drm_add_configs_for_visuals(_EGLDisplay *disp)
};
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
- config_count + 1, EGL_WINDOW_BIT, attr_list, NULL, NULL);
+ config_count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ attr_list, NULL, NULL);
if (dri2_conf) {
if (dri2_conf->base.ConfigID == config_count + 1)
config_count++;
@@ -672,6 +761,7 @@ static const struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
.authenticate = dri2_drm_authenticate,
.create_window_surface = dri2_drm_create_window_surface,
.create_pixmap_surface = dri2_drm_create_pixmap_surface,
+ .create_pbuffer_surface = dri2_drm_create_pbuffer_surface,
.destroy_surface = dri2_drm_destroy_surface,
.create_image = dri2_drm_create_image_khr,
.swap_buffers = dri2_drm_swap_buffers,
--
2.17.1

View file

@ -0,0 +1,376 @@
From 77ee240cc68da64fed3e5630c0cae6a608403e92 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 2 Sep 2021 22:47:54 +0100
Subject: [PATCH 039/168] egl/null: expose EXT_yuv_surface support
---
src/egl/drivers/dri2/platform_null.c | 247 +++++++++++++++++++++++++--
1 file changed, 233 insertions(+), 14 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index 0ce7e60030b..c78e1fe0880 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -79,6 +79,70 @@ uint32_t get_back_buffer_id(struct dri2_egl_surface *dri2_surf)
.prop_value = value, \
}
+static const struct dri2_null_yuv_attrib {
+ uint32_t order;
+ uint32_t subsample;
+ uint32_t num_planes;
+ uint32_t plane_bpp;
+} dri2_null_yuv_attribs[] = {
+ {
+ /* __DRI_IMAGE_FORMAT_YUYV */
+ .order = __DRI_ATTRIB_YUV_ORDER_YUYV_BIT,
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT,
+ .num_planes = 1,
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
+ },
+ {
+ /* __DRI_IMAGE_FORMAT_NV12 */
+ .order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT,
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT,
+ .num_planes = 2,
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
+ },
+ {
+ /* __DRI_IMAGE_FORMAT_NV21 */
+ .order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT,
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT,
+ .num_planes = 2,
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
+ },
+ {
+ /* __DRI_IMAGE_FORMAT_YU12 */
+ .order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT,
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT,
+ .num_planes = 3,
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
+ },
+ {
+ /* __DRI_IMAGE_FORMAT_YV12 */
+ .order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT,
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT,
+ .num_planes = 3,
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
+ },
+ {
+ /* __DRI_IMAGE_FORMAT_UYVY */
+ .order = __DRI_ATTRIB_YUV_ORDER_UYVY_BIT,
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT,
+ .num_planes = 1,
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
+ },
+ {
+ /* __DRI_IMAGE_FORMAT_YVYU */
+ .order = __DRI_ATTRIB_YUV_ORDER_YVYU_BIT,
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT,
+ .num_planes = 1,
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
+ },
+ {
+ /* __DRI_IMAGE_FORMAT_VYUY */
+ .order = __DRI_ATTRIB_YUV_ORDER_VYUY_BIT,
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT,
+ .num_planes = 1,
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
+ },
+};
+
/*
* The index of entries in this table is used as a bitmask in
* dri2_dpy->formats, which tracks the formats supported by the display.
@@ -88,24 +152,84 @@ static const struct dri2_null_format {
int dri_image_format;
int rgba_shifts[4];
unsigned int rgba_sizes[4];
+ const struct dri2_null_yuv_attrib *yuv;
} dri2_null_formats[] = {
{
.drm_format = DRM_FORMAT_XRGB8888,
.dri_image_format = __DRI_IMAGE_FORMAT_XRGB8888,
.rgba_shifts = { 16, 8, 0, -1 },
.rgba_sizes = { 8, 8, 8, 0 },
+ .yuv = NULL,
},
{
.drm_format = DRM_FORMAT_ARGB8888,
.dri_image_format = __DRI_IMAGE_FORMAT_ARGB8888,
.rgba_shifts = { 16, 8, 0, 24 },
.rgba_sizes = { 8, 8, 8, 8 },
+ .yuv = NULL,
},
{
.drm_format = DRM_FORMAT_RGB565,
.dri_image_format = __DRI_IMAGE_FORMAT_RGB565,
.rgba_shifts = { 11, 5, 0, -1 },
.rgba_sizes = { 5, 6, 5, 0 },
+ .yuv = NULL,
+ },
+ {
+ .drm_format = DRM_FORMAT_YUYV,
+ .dri_image_format = __DRI_IMAGE_FORMAT_YUYV,
+ .rgba_shifts = { -1, -1, -1, -1 },
+ .rgba_sizes = { 0, 0, 0, 0 },
+ .yuv = &dri2_null_yuv_attribs[0],
+ },
+ {
+ .drm_format = DRM_FORMAT_NV12,
+ .dri_image_format = __DRI_IMAGE_FORMAT_NV12,
+ .rgba_shifts = { -1, -1, -1, -1 },
+ .rgba_sizes = { 0, 0, 0, 0 },
+ .yuv = &dri2_null_yuv_attribs[1],
+ },
+ {
+ .drm_format = DRM_FORMAT_NV21,
+ .dri_image_format = __DRI_IMAGE_FORMAT_NV21,
+ .rgba_shifts = { -1, -1, -1, -1 },
+ .rgba_sizes = { 0, 0, 0, 0 },
+ .yuv = &dri2_null_yuv_attribs[2],
+ },
+ {
+ .drm_format = DRM_FORMAT_YUV420,
+ .dri_image_format = __DRI_IMAGE_FORMAT_YU12,
+ .rgba_shifts = { -1, -1, -1, -1 },
+ .rgba_sizes = { 0, 0, 0, 0 },
+ .yuv = &dri2_null_yuv_attribs[3],
+ },
+ {
+ .drm_format = DRM_FORMAT_YVU420,
+ .dri_image_format = __DRI_IMAGE_FORMAT_YV12,
+ .rgba_shifts = { -1, -1, -1, -1 },
+ .rgba_sizes = { 0, 0, 0, 0 },
+ .yuv = &dri2_null_yuv_attribs[4],
+ },
+ {
+ .drm_format = DRM_FORMAT_UYVY,
+ .dri_image_format = __DRI_IMAGE_FORMAT_UYVY,
+ .rgba_shifts = { -1, -1, -1, -1 },
+ .rgba_sizes = { 0, 0, 0, 0 },
+ .yuv = &dri2_null_yuv_attribs[5],
+ },
+ {
+ .drm_format = DRM_FORMAT_YVYU,
+ .dri_image_format = __DRI_IMAGE_FORMAT_YVYU,
+ .rgba_shifts = { -1, -1, -1, -1 },
+ .rgba_sizes = { 0, 0, 0, 0 },
+ .yuv = &dri2_null_yuv_attribs[6],
+ },
+ {
+ .drm_format = DRM_FORMAT_VYUY,
+ .dri_image_format = __DRI_IMAGE_FORMAT_VYUY,
+ .rgba_shifts = { -1, -1, -1, -1 },
+ .rgba_sizes = { 0, 0, 0, 0 },
+ .yuv = &dri2_null_yuv_attribs[7],
},
};
@@ -137,6 +261,36 @@ format_idx_get_from_config(struct dri2_egl_display *dri2_dpy,
return -1;
}
+static int
+yuv_format_idx_get_from_config(struct dri2_egl_display *dri2_dpy,
+ const __DRIconfig *dri_config)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(dri2_null_formats); i++) {
+ const struct dri2_null_yuv_attrib *yuv = dri2_null_formats[i].yuv;
+ unsigned order, subsample, num_planes, plane_bpp;
+
+ if (!yuv)
+ continue;
+
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_ORDER,
+ &order);
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_SUBSAMPLE,
+ &subsample);
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_NUMBER_OF_PLANES,
+ &num_planes);
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_PLANE_BPP,
+ &plane_bpp);
+
+ if (order != yuv->order || subsample != yuv->subsample ||
+ num_planes != yuv->num_planes || plane_bpp != yuv->plane_bpp)
+ continue;
+
+ return i;
+ }
+
+ return -1;
+}
+
static int
format_idx_get_from_dri_image_format(uint32_t dri_image_format)
{
@@ -1082,23 +1236,21 @@ static bool
add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
uint32_t *fb_id_out)
{
- uint64_t modifiers[4] = {0};
+ int handle, stride, width, height, format, l_mod, h_mod, offset;
+ uint64_t modifier = DRM_FORMAT_MOD_INVALID;
+ uint64_t *modifiers = NULL, mods[4] = {0};
uint32_t handles[4] = {0};
uint32_t pitches[4] = {0};
uint32_t offsets[4] = {0};
+ __DRIimage *p_image;
uint32_t flags = 0;
- int handle, stride, width, height, format, l_mod, h_mod;
int format_idx;
+ int num_planes;
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HANDLE, &handle);
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_WIDTH, &width);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HEIGHT, &height);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
- handles[0] = (uint32_t) handle;
- pitches[0] = (uint32_t) stride;
-
format_idx = format_idx_get_from_dri_image_format(format);
assert(format_idx != -1);
@@ -1106,10 +1258,44 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, &h_mod);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, &l_mod);
- modifiers[0] = combine_u32_into_u64((uint32_t) h_mod, (uint32_t) l_mod);
+ modifier = combine_u32_into_u64((uint32_t) h_mod, (uint32_t) l_mod);
+ modifiers = mods;
+
flags |= DRM_MODE_FB_MODIFIERS;
}
+ dri2_dpy->image->queryImage(image,
+ __DRI_IMAGE_ATTRIB_NUM_PLANES, &num_planes);
+ if (num_planes <= 0)
+ num_planes = 1;
+
+ for (int i = 0; i < num_planes; i++) {
+ if (dri2_dpy->in_formats_enabled) {
+ assert(modifiers && modifier != DRM_FORMAT_MOD_INVALID);
+ modifiers[i] = modifier;
+ }
+
+ p_image = dri2_dpy->image->fromPlanar(image, i, NULL);
+ if (!p_image) {
+ assert(i == 0);
+ p_image = image;
+ }
+
+ dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_STRIDE,
+ &stride);
+ dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_OFFSET,
+ &offset);
+ dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_HANDLE,
+ &handle);
+
+ if (p_image != image)
+ dri2_dpy->image->destroyImage(p_image);
+
+ pitches[i] = (uint32_t) stride;
+ offsets[i] = (uint32_t) offset;
+ handles[i] = (uint32_t) handle;
+ }
+
return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height,
dri2_null_formats[format_idx].drm_format,
handles, pitches, offsets, modifiers,
@@ -1256,6 +1442,7 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
struct dri2_egl_config *dri2_config = dri2_egl_config(config);
struct dri2_egl_surface *dri2_surf;
const __DRIconfig *dri_config;
+ unsigned int render_type;
_EGLSurface *surf;
int format_idx;
bool ret;
@@ -1286,7 +1473,14 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
goto err_free_surface;
}
- format_idx = format_idx_get_from_config(dri2_dpy, dri_config);
+ if (!dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_RENDER_TYPE,
+ &render_type))
+ goto err_free_surface;
+
+ if (render_type & __DRI_ATTRIB_YUV_BIT)
+ format_idx = yuv_format_idx_get_from_config(dri2_dpy, dri_config);
+ else
+ format_idx = format_idx_get_from_config(dri2_dpy, dri_config);
assert(format_idx != -1);
dri2_surf->format = dri2_null_formats[format_idx].dri_image_format;
@@ -1627,6 +1821,17 @@ dri2_null_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format,
return 1;
}
+static unsigned
+dri2_null_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
+{
+ switch (cap) {
+ case DRI_LOADER_CAP_YUV_SURFACE_IMG:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
static void
dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
{
@@ -1635,10 +1840,11 @@ dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
}
static const __DRIimageLoaderExtension image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 1 },
+ .base = { __DRI_IMAGE_LOADER, 2 },
.getBuffers = dri2_null_image_get_buffers,
.flushFrontBuffer = dri2_null_flush_front_buffer,
+ .getCapability = dri2_null_get_capability,
};
static const __DRIextension *image_loader_extensions[] = {
@@ -1720,10 +1926,24 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp)
for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
struct dri2_egl_config *dri2_conf;
+ EGLint surface_type = EGL_WINDOW_BIT;
+ unsigned int render_type;
int format_idx;
- format_idx = format_idx_get_from_config(dri2_dpy,
- dri2_dpy->driver_configs[i]);
+ if (!dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+ __DRI_ATTRIB_RENDER_TYPE,
+ &render_type))
+ continue;
+
+ if (render_type & __DRI_ATTRIB_YUV_BIT) {
+ format_idx = yuv_format_idx_get_from_config(dri2_dpy,
+ dri2_dpy->driver_configs[i]);
+ } else {
+ format_idx = format_idx_get_from_config(dri2_dpy,
+ dri2_dpy->driver_configs[i]);
+ surface_type |= EGL_PBUFFER_BIT;
+ }
+
if (format_idx == -1)
continue;
@@ -1735,8 +1955,7 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp)
dri2_conf = dri2_add_config(disp,
dri2_dpy->driver_configs[i], count + 1,
- EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
- NULL, NULL, NULL);
+ surface_type, NULL, NULL, NULL);
if (dri2_conf)
count++;
}
--
2.17.1

View file

@ -0,0 +1,442 @@
From a161ef637586f2fd15f498479a163c441c3e6f94 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 9 Mar 2021 17:15:30 +0000
Subject: [PATCH 040/168] dri: preserve the original FD for driver use.
If an application uses a different GPU from the default, allow the
file descriptor (FD) for that original GPU/display to be preserved
for use by drivers. Drivers may wish to use the original FD to
allocate shared surfaces, to ensure the surface properties are
compatible with the original GPU/display (e.g. for X11 or Wayland).
This feature is only available on platforms that choose to support
it, by implementing the new getDisplayFD function in the DRI image,
and DRI2 loader extensions.
If the feature is available, drivers can obtain the original FD
by calling the getDisplayFD function in the relevant loader extension.
Drivers should check the FD is valid before use (i.e. not -1). If
the FD is valid, it may be equal to the current GPU FD if a different
GPU is not being used. The FD is owned by the platform, not the
driver, and the platform is responsible for closing it.
The feature is currently supported by the Wayland, and DRI3 based
X11 EGL and GLX platforms.
---
include/GL/internal/dri_interface.h | 26 +++++++++++++++++--
src/egl/drivers/dri2/egl_dri2.c | 12 ++++++++-
src/egl/drivers/dri2/egl_dri2.h | 1 +
src/egl/drivers/dri2/platform_wayland.c | 31 ++++++++++++++++++++--
src/egl/drivers/dri2/platform_x11.c | 3 +++
src/egl/drivers/dri2/platform_x11_dri3.c | 27 ++++++++++++++++++-
src/glx/dri3_glx.c | 33 ++++++++++++++++++++++--
src/glx/dri3_priv.h | 1 +
8 files changed, 126 insertions(+), 8 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 66a60fd46ad..22c1374af02 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1015,7 +1015,7 @@ struct __DRIbufferRec {
};
#define __DRI_DRI2_LOADER "DRI_DRI2Loader"
-#define __DRI_DRI2_LOADER_VERSION 5
+#define __DRI_DRI2_LOADER_VERSION 6
enum dri_loader_cap {
/* Whether the loader handles RGBA channel ordering correctly. If not,
@@ -1096,6 +1096,17 @@ struct __DRIdri2LoaderExtensionRec {
* \since 5
*/
void (*destroyLoaderImageState)(void *loaderPrivate);
+
+ /**
+ * Get the display FD
+ *
+ * Get the FD of the display device.
+ *
+ * \param loaderPrivate The last parameter of createNewScreen or
+ * createNewScreen2.
+ * \since 6
+ */
+ int (*getDisplayFD)(void *loaderPrivate);
};
/**
@@ -2054,7 +2065,7 @@ struct __DRIimageList {
};
#define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
-#define __DRI_IMAGE_LOADER_VERSION 4
+#define __DRI_IMAGE_LOADER_VERSION 5
struct __DRIimageLoaderExtensionRec {
__DRIextension base;
@@ -2122,6 +2133,17 @@ struct __DRIimageLoaderExtensionRec {
* \since 4
*/
void (*destroyLoaderImageState)(void *loaderPrivate);
+
+ /**
+ * Get the display FD
+ *
+ * Get the FD of the display device.
+ *
+ * \param loaderPrivate The last parameter of createNewScreen or
+ * createNewScreen2.
+ * \since 5
+ */
+ int (*getDisplayFD)(void *loaderPrivate);
};
/**
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 60cc81ba536..0bcc5054070 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1381,6 +1381,16 @@ dri2_display_destroy(_EGLDisplay *disp)
break;
}
+ switch (disp->Platform) {
+ case _EGL_PLATFORM_WAYLAND:
+ case _EGL_PLATFORM_X11:
+ if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
+ close(dri2_dpy->fd_dpy);
+ break;
+ default:
+ break;
+ }
+
if (dri2_dpy->fd >= 0)
close(dri2_dpy->fd);
@@ -3596,7 +3606,7 @@ dri2_bind_wayland_display_wl(_EGLDisplay *disp, struct wl_display *wl_dpy)
if (dri2_dpy->wl_server_drm)
goto fail;
- device_name = drmGetRenderDeviceNameFromFd(dri2_dpy->fd);
+ device_name = drmGetRenderDeviceNameFromFd(dri2_dpy->fd_dpy);
if (!device_name)
device_name = strdup(dri2_dpy->device_name);
if (!device_name)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 29f24f57a63..21e77a194e0 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -267,6 +267,7 @@ struct dri2_egl_display
const __DRIconfigOptionsExtension *configOptions;
const __DRImutableRenderBufferDriverExtension *mutable_render_buffer;
int fd;
+ int fd_dpy;
/* dri2_initialize/dri2_terminate increment/decrement this count, so does
* dri2_make_current (tracks if there are active contexts/surfaces). */
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 86a9305178d..7cc6dc0cad6 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -44,6 +44,7 @@
#include "loader.h"
#include "util/u_vector.h"
#include "util/anon_file.h"
+#include "util/os_file.h"
#include "eglglobals.h"
#include "kopper_interface.h"
@@ -1448,21 +1449,32 @@ dri2_wl_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
}
}
+static int
+dri2_wl_get_display_fd(void *loaderPrivate)
+{
+ _EGLDisplay *disp = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ return dri2_dpy->fd_dpy;
+}
+
static const __DRIdri2LoaderExtension dri2_loader_extension = {
- .base = { __DRI_DRI2_LOADER, 4 },
+ .base = { __DRI_DRI2_LOADER, 6 },
.getBuffers = dri2_wl_get_buffers,
.flushFrontBuffer = dri2_wl_flush_front_buffer,
.getBuffersWithFormat = dri2_wl_get_buffers_with_format,
.getCapability = dri2_wl_get_capability,
+ .getDisplayFD = dri2_wl_get_display_fd,
};
static const __DRIimageLoaderExtension image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 2 },
+ .base = { __DRI_IMAGE_LOADER, 5 },
.getBuffers = image_get_buffers,
.flushFrontBuffer = dri2_wl_flush_front_buffer,
.getCapability = dri2_wl_get_capability,
+ .getDisplayFD = dri2_wl_get_display_fd,
};
static void
@@ -2253,12 +2265,14 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
{
_EGLDevice *dev;
struct dri2_egl_display *dri2_dpy;
+ int fd_old;
dri2_dpy = calloc(1, sizeof *dri2_dpy);
if (!dri2_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
+ dri2_dpy->fd_dpy = -1;
disp->DriverData = (void *) dri2_dpy;
if (dri2_wl_formats_init(&dri2_dpy->formats) < 0)
@@ -2330,8 +2344,20 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
goto cleanup;
}
+ fd_old = dri2_dpy->fd;
+ dri2_dpy->fd_dpy = os_dupfd_cloexec(dri2_dpy->fd);
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd,
&dri2_dpy->is_different_gpu);
+ if (dri2_dpy->fd == fd_old) {
+ if (dri2_dpy->fd_dpy != -1)
+ close(dri2_dpy->fd_dpy);
+
+ dri2_dpy->fd_dpy = dri2_dpy->fd;
+ } else if (dri2_dpy->fd_dpy == -1) {
+ _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to dup display FD");
+ goto cleanup;
+ }
+
dev = _eglAddDevice(dri2_dpy->fd, false);
if (!dev) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
@@ -2908,6 +2934,7 @@ dri2_initialize_wayland_swrast(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
+ dri2_dpy->fd_dpy = -1;
disp->DriverData = (void *) dri2_dpy;
if (dri2_wl_formats_init(&dri2_dpy->formats) < 0)
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index 15be86dc026..389c1054461 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -1507,6 +1507,7 @@ dri2_initialize_x11_swrast(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
+ dri2_dpy->fd_dpy = -1;
if (!dri2_get_xcb_connection(disp, dri2_dpy))
goto cleanup;
@@ -1596,6 +1597,7 @@ dri2_initialize_x11_dri3(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
+ dri2_dpy->fd_dpy = -1;
if (!dri2_get_xcb_connection(disp, dri2_dpy))
goto cleanup;
@@ -1708,6 +1710,7 @@ dri2_initialize_x11_dri2(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
+ dri2_dpy->fd_dpy = -1;
if (!dri2_get_xcb_connection(disp, dri2_dpy))
goto cleanup;
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
index c529f426f5e..8fd794bce99 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -32,6 +32,7 @@
#include <xf86drm.h>
#include "util/macros.h"
+#include "util/os_file.h"
#include "egl_dri2.h"
#include "platform_x11_dri3.h"
@@ -431,11 +432,21 @@ dri3_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate)
_eglLog(_EGL_WARNING, "FIXME: egl/x11 doesn't support front buffer rendering.");
}
+static int
+dri3_get_display_fd(void *loaderPrivate)
+{
+ _EGLDisplay *disp = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ return dri2_dpy->fd_dpy;
+}
+
const __DRIimageLoaderExtension dri3_image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 1 },
+ .base = { __DRI_IMAGE_LOADER, 5 },
.getBuffers = loader_dri3_get_buffers,
.flushFrontBuffer = dri3_flush_front_buffer,
+ .getDisplayFD = dri3_get_display_fd,
};
static EGLBoolean
@@ -555,6 +566,7 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
xcb_xfixes_query_version_cookie_t xfixes_query_cookie;
xcb_generic_error_t *error;
const xcb_query_extension_reply_t *extension;
+ int fd_old;
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri3_id);
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_present_id);
@@ -634,12 +646,25 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
return EGL_FALSE;
}
+ fd_old = dri2_dpy->fd;
+ dri2_dpy->fd_dpy = os_dupfd_cloexec(dri2_dpy->fd);
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd, &dri2_dpy->is_different_gpu);
+ if (dri2_dpy->fd == fd_old) {
+ if (dri2_dpy->fd_dpy != -1)
+ close(dri2_dpy->fd_dpy);
+
+ dri2_dpy->fd_dpy = dri2_dpy->fd;
+ } else if (dri2_dpy->fd_dpy == -1) {
+ _eglLog(_EGL_WARNING, "DRI3: failed to dup display FD");
+ close(dri2_dpy->fd);
+ return EGL_FALSE;
+ }
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
if (!dri2_dpy->driver_name) {
_eglLog(_EGL_WARNING, "DRI3: No driver found");
close(dri2_dpy->fd);
+ close(dri2_dpy->fd_dpy);
return EGL_FALSE;
}
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index e8996dd5e27..f6eb405d130 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -78,6 +78,7 @@
#include "loader.h"
#include "loader_dri_helper.h"
#include "dri2.h"
+#include "util/os_file.h"
static struct dri3_drawable *
loader_drawable_to_dri3_drawable(struct loader_dri3_drawable *draw) {
@@ -537,6 +538,14 @@ dri3_flush_swap_buffers(__DRIdrawable *driDrawable, void *loaderPrivate)
loader_dri3_swapbuffer_barrier(draw);
}
+static int
+dri3_get_display_fd(void *loaderPrivate)
+{
+ struct dri3_screen *psc = (struct dri3_screen *)loaderPrivate;
+
+ return psc->fd_dpy;
+}
+
static void
dri_set_background_context(void *loaderPrivate)
{
@@ -555,11 +564,12 @@ dri_is_thread_safe(void *loaderPrivate)
/* The image loader extension record for DRI3
*/
static const __DRIimageLoaderExtension imageLoaderExtension = {
- .base = { __DRI_IMAGE_LOADER, 3 },
+ .base = { __DRI_IMAGE_LOADER, 5 },
.getBuffers = loader_dri3_get_buffers,
.flushFrontBuffer = dri3_flush_front_buffer,
.flushSwapBuffers = dri3_flush_swap_buffers,
+ .getDisplayFD = dri3_get_display_fd,
};
const __DRIuseInvalidateExtension dri3UseInvalidate = {
@@ -625,6 +635,10 @@ dri3_destroy_screen(struct glx_screen *base)
loader_dri3_close_screen(psc->driScreen);
(*psc->core->destroyScreen) (psc->driScreen);
driDestroyConfigs(psc->driver_configs);
+
+ if (psc->fd_dpy != psc->fd)
+ close(psc->fd_dpy);
+
close(psc->fd);
free(psc);
}
@@ -835,8 +849,9 @@ dri3_create_screen(int screen, struct glx_display * priv)
struct dri3_screen *psc;
__GLXDRIscreen *psp;
struct glx_config *configs = NULL, *visuals = NULL;
- char *driverName, *driverNameDisplayGPU, *tmp;
+ char *driverName = NULL, *driverNameDisplayGPU, *tmp;
int i;
+ int fd_old;
psc = calloc(1, sizeof *psc);
if (psc == NULL)
@@ -844,6 +859,7 @@ dri3_create_screen(int screen, struct glx_display * priv)
psc->fd = -1;
psc->fd_display_gpu = -1;
+ psc->fd_dpy = -1;
if (!glx_screen_init(&psc->base, screen, priv)) {
free(psc);
@@ -864,12 +880,23 @@ dri3_create_screen(int screen, struct glx_display * priv)
return NULL;
}
+ fd_old = psc->fd;
+ psc->fd_dpy = os_dupfd_cloexec(psc->fd);
psc->fd_display_gpu = fcntl(psc->fd, F_DUPFD_CLOEXEC, 3);
psc->fd = loader_get_user_preferred_fd(psc->fd, &psc->is_different_gpu);
if (!psc->is_different_gpu) {
close(psc->fd_display_gpu);
psc->fd_display_gpu = -1;
}
+ if (psc->fd == fd_old) {
+ if (psc->fd_dpy != -1)
+ close(psc->fd_dpy);
+
+ psc->fd_dpy = psc->fd;
+ } else if (psc->fd_dpy == -1) {
+ ErrorMessageF("Unable to dup the display FD");
+ goto handle_error;
+ }
driverName = loader_get_driver_for_fd(psc->fd);
if (!driverName) {
@@ -1075,6 +1102,8 @@ handle_error:
if (psc->driScreenDisplayGPU)
psc->core->destroyScreen(psc->driScreenDisplayGPU);
psc->driScreenDisplayGPU = NULL;
+ if (psc->fd_dpy >= 0 && psc->fd_dpy != psc->fd)
+ close(psc->fd_dpy);
if (psc->fd >= 0)
close(psc->fd);
if (psc->fd_display_gpu >= 0)
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index 09dcefd6115..bd3073dc4b6 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -101,6 +101,7 @@ struct dri3_screen {
void *driver;
int fd;
+ int fd_dpy;
bool is_different_gpu;
bool prefer_back_buffer_reuse;
--
2.17.1

View file

@ -0,0 +1,131 @@
From ed92d2bf22f666cbc9bd79e6baf23b83722e78f6 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 28 Apr 2021 10:57:15 +0100
Subject: [PATCH 041/168] egl/wayland: a linear buffer is not needed with DRM
format modifiers
If the compositor supports DRM format modifiers, there is no
need for an additional linear buffer, as the client can allocate
buffers with attributes known to the compositor.
---
src/egl/drivers/dri2/platform_wayland.c | 36 ++++++++++++++-----------
1 file changed, 21 insertions(+), 15 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 7cc6dc0cad6..3a9f43e6069 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -1014,7 +1014,7 @@ create_dri_image_diff_gpu(struct dri2_egl_surface *dri2_surf,
&linear_mod, 1, NULL);
}
-static void
+static bool
create_dri_image_from_dmabuf_feedback(struct dri2_egl_surface *dri2_surf,
unsigned int dri_image_format, uint32_t use_flags)
{
@@ -1027,7 +1027,7 @@ create_dri_image_from_dmabuf_feedback(struct dri2_egl_surface *dri2_surf,
/* We don't have valid dma-buf feedback, so return */
if (dri2_surf->dmabuf_feedback.main_device == 0)
- return;
+ return false;
visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
assert(visual_idx != -1);
@@ -1071,11 +1071,13 @@ create_dri_image_from_dmabuf_feedback(struct dri2_egl_surface *dri2_surf,
modifiers, num_modifiers, NULL);
if (dri2_surf->back->dri_image)
- return;
+ return num_modifiers != 0;
}
+
+ return false;
}
-static void
+static bool
create_dri_image(struct dri2_egl_surface *dri2_surf,
unsigned int dri_image_format, uint32_t use_flags)
{
@@ -1107,6 +1109,8 @@ create_dri_image(struct dri2_egl_surface *dri2_surf,
dri_image_format,
dri2_dpy->is_different_gpu ? 0 : use_flags,
modifiers, num_modifiers, NULL);
+
+ return num_modifiers != 0;
}
static int
@@ -1118,6 +1122,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
int visual_idx;
unsigned int dri_image_format;
unsigned int linear_dri_image_format;
+ bool have_modifiers = false;
visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
assert(visual_idx != -1);
@@ -1177,23 +1182,24 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
use_flags |= __DRI_IMAGE_USE_PROTECTED;
}
- if (dri2_dpy->is_different_gpu && dri2_surf->back->linear_copy == NULL) {
- create_dri_image_diff_gpu(dri2_surf, linear_dri_image_format, use_flags);
- if (dri2_surf->back->linear_copy == NULL)
- return -1;
- }
-
if (dri2_surf->back->dri_image == NULL) {
if (dri2_surf->wl_dmabuf_feedback)
- create_dri_image_from_dmabuf_feedback(dri2_surf, dri_image_format, use_flags);
+ have_modifiers = create_dri_image_from_dmabuf_feedback(dri2_surf, dri_image_format, use_flags);
if (dri2_surf->back->dri_image == NULL)
- create_dri_image(dri2_surf, dri_image_format, use_flags);
+ have_modifiers = create_dri_image(dri2_surf, dri_image_format, use_flags);
dri2_surf->back->age = 0;
}
if (dri2_surf->back->dri_image == NULL)
return -1;
+ if (dri2_dpy->is_different_gpu && !have_modifiers &&
+ dri2_surf->back->linear_copy == NULL) {
+ create_dri_image_diff_gpu(dri2_surf, linear_dri_image_format, use_flags);
+ if (dri2_surf->back->linear_copy == NULL)
+ return -1;
+ }
+
dri2_surf->back->locked = true;
return 0;
@@ -1283,7 +1289,7 @@ update_buffers(struct dri2_egl_display *dri2_dpy,
dri2_surf->color_buffers[i].age > BUFFER_TRIM_AGE_HYSTERESIS) {
wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
- if (dri2_dpy->is_different_gpu)
+ if (dri2_surf->color_buffers[i].linear_copy)
dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy);
dri2_surf->color_buffers[i].wl_buffer = NULL;
dri2_surf->color_buffers[i].dri_image = NULL;
@@ -1728,7 +1734,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
if (!dri2_surf->current->wl_buffer) {
__DRIimage *image;
- if (dri2_dpy->is_different_gpu)
+ if (dri2_surf->current->linear_copy)
image = dri2_surf->current->linear_copy;
else
image = dri2_surf->current->dri_image;
@@ -1760,7 +1766,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
wl_surface_damage(dri2_surf->wl_surface_wrapper,
0, 0, INT32_MAX, INT32_MAX);
- if (dri2_dpy->is_different_gpu) {
+ if (dri2_surf->current->linear_copy) {
_EGLContext *ctx = _eglGetCurrentContext();
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
dri2_dpy->image->blitImage(dri2_ctx->dri_context,
--
2.17.1

View file

@ -0,0 +1,303 @@
From d4d79415ca824cee38f8c8cdcdfe108179d092c0 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 28 Apr 2021 16:33:42 +0100
Subject: [PATCH 042/168] dri3: a linear buffer is not needed with DRM format
modifiers
If the X Server supports DRM format modifiers, there is no need
for an additional linear buffer, as the client can allocate buffers
with attributes known to the Server.
---
src/egl/drivers/dri2/platform_x11_dri3.c | 7 +-
src/glx/dri3_glx.c | 137 +++++++++++++++--------
src/loader/loader_dri3_helper.c | 15 +++
src/loader/loader_dri3_helper.h | 3 +
4 files changed, 112 insertions(+), 50 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
index 8fd794bce99..63d3dc589d7 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -158,6 +158,7 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
struct dri3_egl_surface *dri3_surf;
const __DRIconfig *dri_config;
xcb_drawable_t drawable;
+ bool is_incompat_gpu;
dri3_surf = calloc(1, sizeof *dri3_surf);
if (!dri3_surf) {
@@ -165,6 +166,10 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
return NULL;
}
+ is_incompat_gpu = dri2_dpy->is_different_gpu &&
+ !loader_dri3_has_modifiers(dri2_dpy->multibuffers_available,
+ dri2_dpy->image);
+
if (!dri2_init_surface(&dri3_surf->surf.base, disp, type, conf,
attrib_list, false, native_surface))
goto cleanup_surf;
@@ -190,7 +195,7 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
if (loader_dri3_drawable_init(dri2_dpy->conn, drawable,
egl_to_loader_dri3_drawable_type(type),
dri2_dpy->dri_screen,
- dri2_dpy->is_different_gpu,
+ is_incompat_gpu,
dri2_dpy->multibuffers_available,
true,
dri_config,
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index f6eb405d130..6921ed9fcb5 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -358,6 +358,21 @@ glx_to_loader_dri3_drawable_type(int type)
}
}
+static bool
+dri3_has_multibuffer(const __DRIimageExtension *image,
+ const struct dri3_display *pdp)
+{
+#ifdef HAVE_DRI3_MODIFIERS
+ return (image && image->base.version >= 15) &&
+ (pdp->dri3Major > 1 ||
+ (pdp->dri3Major == 1 && pdp->dri3Minor >= 2)) &&
+ (pdp->presentMajor > 1 ||
+ (pdp->presentMajor == 1 && pdp->presentMinor >= 2));
+#else
+ return false;
+#endif
+}
+
static __GLXDRIdrawable *
dri3_create_drawable(struct glx_screen *base, XID xDrawable,
GLXDrawable drawable, int type,
@@ -366,11 +381,9 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable,
struct dri3_drawable *pdraw;
struct dri3_screen *psc = (struct dri3_screen *) base;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
- bool has_multibuffer = false;
-#ifdef HAVE_DRI3_MODIFIERS
const struct dri3_display *const pdp = (struct dri3_display *)
base->display->dri3Display;
-#endif
+ bool has_multibuffer = dri3_has_multibuffer(psc->image, pdp);
pdraw = calloc(1, sizeof(*pdraw));
if (!pdraw)
@@ -381,14 +394,6 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable,
pdraw->base.drawable = drawable;
pdraw->base.psc = &psc->base;
-#ifdef HAVE_DRI3_MODIFIERS
- if ((psc->image && psc->image->base.version >= 15) &&
- (pdp->dri3Major > 1 || (pdp->dri3Major == 1 && pdp->dri3Minor >= 2)) &&
- (pdp->presentMajor > 1 ||
- (pdp->presentMajor == 1 && pdp->presentMinor >= 2)))
- has_multibuffer = true;
-#endif
-
(void) __glXInitialize(psc->base.dpy);
if (loader_dri3_drawable_init(XGetXCBConnection(base->dpy),
@@ -728,13 +733,14 @@ static const struct glx_context_vtable dri3_context_vtable = {
.interop_flush_objects = dri3_interop_flush_objects
};
-/** dri3_bind_extensions
+/** dri3_bind_extensions_part1
*
- * Enable all of the extensions supported on DRI3
+ * Enable the extensions supported on DRI3 that don't depend on
+ * whether we are using a different GPU.
*/
static void
-dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv,
- const char *driverName)
+dri3_bind_extensions_part1(struct dri3_screen *psc, struct glx_display * priv,
+ const char *driverName)
{
const __DRIextension **extensions;
unsigned mask;
@@ -765,16 +771,6 @@ dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv,
}
for (i = 0; extensions[i]; i++) {
- /* when on a different gpu than the server, the server pixmaps
- * can have a tiling mode we can't read. Thus we can't create
- * a texture from them.
- */
- if (!psc->is_different_gpu &&
- (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
- psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
- __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap");
- }
-
if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
psc->f = (__DRI2flushExtension *) extensions[i];
/* internal driver extension, no GL extension exposed */
@@ -810,6 +806,33 @@ dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv,
}
}
+/** dri3_bind_extensions_part2
+ *
+ * Enable the extensions supported on DRI3 that depend on whether we
+ * are using a different GPU.
+ */
+static void
+dri3_bind_extensions_part2(struct dri3_screen *psc, struct glx_display * priv,
+ const char *driverName)
+{
+ const __DRIextension **extensions;
+ int i;
+
+ extensions = psc->core->getExtensions(psc->driScreen);
+
+ for (i = 0; extensions[i]; i++) {
+ /* when on a different gpu than the server, the server pixmaps
+ * can have a tiling mode we can't read. Thus we can't create
+ * a texture from them.
+ */
+ if (!psc->is_different_gpu &&
+ (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
+ psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
+ __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap");
+ }
+ }
+}
+
static char *
dri3_get_driver_name(struct glx_screen *glx_screen)
{
@@ -852,6 +875,8 @@ dri3_create_screen(int screen, struct glx_display * priv)
char *driverName = NULL, *driverNameDisplayGPU, *tmp;
int i;
int fd_old;
+ bool is_different_gpu;
+ bool have_modifiers;
psc = calloc(1, sizeof *psc);
if (psc == NULL)
@@ -883,8 +908,8 @@ dri3_create_screen(int screen, struct glx_display * priv)
fd_old = psc->fd;
psc->fd_dpy = os_dupfd_cloexec(psc->fd);
psc->fd_display_gpu = fcntl(psc->fd, F_DUPFD_CLOEXEC, 3);
- psc->fd = loader_get_user_preferred_fd(psc->fd, &psc->is_different_gpu);
- if (!psc->is_different_gpu) {
+ psc->fd = loader_get_user_preferred_fd(psc->fd, &is_different_gpu);
+ if (!is_different_gpu) {
close(psc->fd_display_gpu);
psc->fd_display_gpu = -1;
}
@@ -926,27 +951,6 @@ dri3_create_screen(int screen, struct glx_display * priv)
goto handle_error;
}
- if (psc->is_different_gpu) {
- driverNameDisplayGPU = loader_get_driver_for_fd(psc->fd_display_gpu);
- if (driverNameDisplayGPU) {
-
- /* check if driver name is matching so that non mesa drivers
- * will not crash. Also need this check since image extension
- * pointer from render gpu is shared with display gpu. Image
- * extension pointer is shared because it keeps things simple.
- */
- if (strcmp(driverName, driverNameDisplayGPU) == 0) {
- psc->driScreenDisplayGPU =
- psc->image_driver->createNewScreen2(screen, psc->fd_display_gpu,
- pdp->loader_extensions,
- extensions,
- &driver_configs, psc);
- }
-
- free(driverNameDisplayGPU);
- }
- }
-
psc->driScreen =
psc->image_driver->createNewScreen2(screen, psc->fd,
pdp->loader_extensions,
@@ -958,7 +962,42 @@ dri3_create_screen(int screen, struct glx_display * priv)
goto handle_error;
}
- dri3_bind_extensions(psc, priv, driverName);
+ dri3_bind_extensions_part1(psc, priv, driverName);
+
+ have_modifiers = loader_dri3_has_modifiers(dri3_has_multibuffer(psc->image,
+ pdp),
+ psc->image);
+
+ if (is_different_gpu) {
+ if (have_modifiers) {
+ close(psc->fd_display_gpu);
+ psc->fd_display_gpu = -1;
+ } else {
+ driverNameDisplayGPU = loader_get_driver_for_fd(psc->fd_display_gpu);
+ if (driverNameDisplayGPU) {
+
+ /* check if driver name is matching so that non mesa drivers
+ * will not crash. Also need this check since image extension
+ * pointer from render gpu is shared with display gpu. Image
+ * extension pointer is shared because it keeps things simple.
+ */
+ if (strcmp(driverName, driverNameDisplayGPU) == 0) {
+ psc->driScreenDisplayGPU =
+ psc->image_driver->createNewScreen2(screen,
+ psc->fd_display_gpu,
+ pdp->loader_extensions,
+ extensions,
+ &driver_configs, psc);
+ }
+
+ free(driverNameDisplayGPU);
+ }
+ }
+ }
+
+ psc->is_different_gpu = is_different_gpu && !have_modifiers;
+
+ dri3_bind_extensions_part2(psc, priv, driverName);
if (!psc->image || psc->image->base.version < 7 || !psc->image->createImageFromFds) {
ErrorMessageF("Version 7 or imageFromFds image extension not found\n");
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index ad6f0b624b3..2192b20116d 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -2597,3 +2597,18 @@ dri3_find_back_alloc(struct loader_dri3_drawable *draw)
return back;
}
+
+bool
+loader_dri3_has_modifiers(bool multiplanes_available,
+ const __DRIimageExtension *image)
+{
+#ifdef HAVE_DRI3_MODIFIERS
+ return multiplanes_available && image &&
+ image->base.version >= 15 &&
+ image->queryDmaBufModifiers &&
+ image->createImageWithModifiers &&
+ image->createImageFromDmaBufs2;
+#else
+ return false;
+#endif
+}
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index 6d20162c47c..8b39af04e9e 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -330,5 +330,8 @@ loader_dri3_update_screen_resources(struct loader_dri3_screen_resources *res);
void
loader_dri3_destroy_screen_resources(struct loader_dri3_screen_resources *res);
+bool
+loader_dri3_has_modifiers(bool multiplanes_available,
+ const __DRIimageExtension *image);
#endif
--
2.17.1

View file

@ -0,0 +1,267 @@
From 9721fffcf5d7ef752963f682bcc94850935e5f05 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 20 May 2021 14:43:29 +0100
Subject: [PATCH 043/168] egl/drm: add support for DRI_PRIME GPU selection
Add support for selecting the GPU to be used for rendering using
the DRI_PRIME environment variable. If a different GPU is selected,
a duplicate of the file descriptor for the original GPU/display is
preserved, which can be obtained by calling the getDisplayFD
function in the image loader extension.
For server side Wayland, the ability to support PRIME is
determined by checking for the PRIME import and export
capabilities on the driver file descriptor, which may no
longer support them if a different GPU from the default has
been selected. It may be that the driver can still support
PRIME; for example, by making use of the original (default)
file descriptor. The driver can indicate it supports PRIME
via the getCapabilities function in the DRI Image extension.
---
include/GL/internal/dri_interface.h | 2 ++
src/egl/drivers/dri2/egl_dri2.c | 10 ++++++++
src/egl/drivers/dri2/platform_drm.c | 19 ++++++++++-----
src/gbm/backends/dri/gbm_dri.c | 38 +++++++++++++++++++++++++----
src/gbm/backends/dri/gbm_driint.h | 8 ++++++
5 files changed, 66 insertions(+), 11 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 22c1374af02..7d96048688d 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1417,6 +1417,8 @@ enum __DRIChromaSiting {
*/
/*@{*/
#define __DRI_IMAGE_CAP_GLOBAL_NAMES 1
+#define __DRI_IMAGE_CAP_PRIME_IMPORT 0x2000
+#define __DRI_IMAGE_CAP_PRIME_EXPORT 0x4000
/*@}*/
/**
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 0bcc5054070..485ceeba9b4 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1382,6 +1382,7 @@ dri2_display_destroy(_EGLDisplay *disp)
}
switch (disp->Platform) {
+ case _EGL_PLATFORM_DRM:
case _EGL_PLATFORM_WAYLAND:
case _EGL_PLATFORM_X11:
if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
@@ -3617,6 +3618,15 @@ dri2_bind_wayland_display_wl(_EGLDisplay *disp, struct wl_display *wl_dpy)
dri2_dpy->image->base.version >= 7 &&
dri2_dpy->image->createImageFromFds != NULL)
flags |= WAYLAND_DRM_PRIME;
+ else if (dri2_dpy->image->base.version >= 10 &&
+ dri2_dpy->image->getCapabilities != NULL) {
+ int capabilities;
+
+ capabilities = dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
+ if ((capabilities & __DRI_IMAGE_CAP_PRIME_IMPORT) != 0 &&
+ (capabilities & __DRI_IMAGE_CAP_PRIME_EXPORT) != 0)
+ flags |= WAYLAND_DRM_PRIME;
+ }
dri2_dpy->wl_server_drm =
wayland_drm_init(wl_dpy, device_name,
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 4d08851c782..19c50c25128 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -595,7 +595,7 @@ dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- return drmAuthMagic(dri2_dpy->fd, id);
+ return drmAuthMagic(dri2_dpy->fd_dpy, id);
}
static void
@@ -782,6 +782,7 @@ dri2_initialize_drm(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
+ dri2_dpy->fd_dpy = -1;
disp->DriverData = (void *) dri2_dpy;
gbm = disp->PlatformDisplay;
@@ -789,16 +790,16 @@ dri2_initialize_drm(_EGLDisplay *disp)
char buf[64];
int n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, 0);
if (n != -1 && n < sizeof(buf))
- dri2_dpy->fd = loader_open_device(buf);
- gbm = gbm_create_device(dri2_dpy->fd);
+ dri2_dpy->fd_dpy = loader_open_device(buf);
+ gbm = gbm_create_device(dri2_dpy->fd_dpy);
if (gbm == NULL) {
err = "DRI2: failed to create gbm device";
goto cleanup;
}
dri2_dpy->own_device = true;
} else {
- dri2_dpy->fd = os_dupfd_cloexec(gbm_device_get_fd(gbm));
- if (dri2_dpy->fd < 0) {
+ dri2_dpy->fd_dpy = os_dupfd_cloexec(gbm_device_get_fd(gbm));
+ if (dri2_dpy->fd_dpy < 0) {
err = "DRI2: failed to fcntl() existing gbm device";
goto cleanup;
}
@@ -810,6 +811,12 @@ dri2_initialize_drm(_EGLDisplay *disp)
goto cleanup;
}
+ if (gbm_dri_device_get_fd(dri2_dpy->gbm_dri) ==
+ gbm_device_get_fd(gbm))
+ dri2_dpy->fd = dri2_dpy->fd_dpy;
+ else
+ dri2_dpy->fd = os_dupfd_cloexec(gbm_dri_device_get_fd(dri2_dpy->gbm_dri));
+
dev = _eglAddDevice(dri2_dpy->fd, dri2_dpy->gbm_dri->software);
if (!dev) {
err = "DRI2: failed to find EGLDevice";
@@ -875,7 +882,7 @@ dri2_initialize_drm(_EGLDisplay *disp)
disp->Extensions.EXT_buffer_age = EGL_TRUE;
#ifdef HAVE_WAYLAND_PLATFORM
- dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
+ dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd_dpy);
#endif
dri2_set_WL_bind_wayland_display(disp);
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index 5b18bdcccbc..bfb48769502 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -52,6 +52,7 @@
#include "loader.h"
#include "util/u_debug.h"
#include "util/macros.h"
+#include "util/os_file.h"
/* For importing wl_buffer */
#if HAVE_WAYLAND_PLATFORM
@@ -164,6 +165,14 @@ image_get_buffers(__DRIdrawable *driDrawable,
surf->dri_private, buffer_mask, buffers);
}
+static int
+dri_get_display_fd(void *loaderPrivate)
+{
+ struct gbm_dri_device *dri = loaderPrivate;
+
+ return dri->base.v0.fd;
+}
+
static void
swrast_get_drawable_info(__DRIdrawable *driDrawable,
int *x,
@@ -245,20 +254,22 @@ static const __DRIimageLookupExtension image_lookup_extension = {
};
static const __DRIdri2LoaderExtension dri2_loader_extension = {
- .base = { __DRI_DRI2_LOADER, 4 },
+ .base = { __DRI_DRI2_LOADER, 6 },
.getBuffers = dri_get_buffers,
.flushFrontBuffer = dri_flush_front_buffer,
.getBuffersWithFormat = dri_get_buffers_with_format,
.getCapability = dri_get_capability,
+ .getDisplayFD = dri_get_display_fd,
};
static const __DRIimageLoaderExtension image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 2 },
+ .base = { __DRI_IMAGE_LOADER, 5 },
.getBuffers = image_get_buffers,
.flushFrontBuffer = dri_flush_front_buffer,
.getCapability = dri_get_capability,
+ .getDisplayFD = dri_get_display_fd,
};
static const __DRIswrastLoaderExtension swrast_loader_extension = {
@@ -431,12 +442,12 @@ dri_screen_create_dri2(struct gbm_dri_device *dri, char *driver_name)
return -1;
if (dri->dri2->base.version >= 4) {
- dri->screen = dri->dri2->createNewScreen2(0, dri->base.v0.fd,
+ dri->screen = dri->dri2->createNewScreen2(0, dri->fd,
dri->loader_extensions,
dri->driver_extensions,
&dri->driver_configs, dri);
} else {
- dri->screen = dri->dri2->createNewScreen(0, dri->base.v0.fd,
+ dri->screen = dri->dri2->createNewScreen(0, dri->fd,
dri->loader_extensions,
&dri->driver_configs, dri);
}
@@ -503,8 +514,20 @@ static int
dri_screen_create(struct gbm_dri_device *dri)
{
char *driver_name;
+ int dup_fd, new_fd;
+ bool is_different_gpu;
- driver_name = loader_get_driver_for_fd(dri->base.v0.fd);
+ dup_fd = os_dupfd_cloexec(dri->fd);
+ if (dup_fd < 0)
+ return -1;
+
+ new_fd = loader_get_user_preferred_fd(dup_fd, &is_different_gpu);
+ if (new_fd == dup_fd)
+ close(new_fd);
+ else
+ dri->fd = new_fd;
+
+ driver_name = loader_get_driver_for_fd(dri->fd);
if (!driver_name)
return -1;
@@ -1486,6 +1509,9 @@ dri_destroy(struct gbm_device *gbm)
dlclose(dri->driver);
free(dri->driver_name);
+ if (dri->fd >= 0 && dri->fd != dri->base.v0.fd)
+ close (dri->fd);
+
free(dri);
}
@@ -1507,6 +1533,8 @@ dri_device_create(int fd, uint32_t gbm_backend_version)
if (!dri)
return NULL;
+ dri->fd = fd;
+
dri->base.v0.fd = fd;
dri->base.v0.backend_version = gbm_backend_version;
dri->base.v0.bo_create = gbm_dri_bo_create;
diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h
index 31f6b67a40f..3f94352185f 100644
--- a/src/gbm/backends/dri/gbm_driint.h
+++ b/src/gbm/backends/dri/gbm_driint.h
@@ -62,6 +62,8 @@ struct gbm_dri_visual {
struct gbm_dri_device {
struct gbm_device base;
+ int fd;
+
void *driver;
char *driver_name; /* Name of the DRI module, without the _dri suffix */
bool software; /* A software driver was loaded */
@@ -195,4 +197,10 @@ gbm_dri_bo_unmap_dumb(struct gbm_dri_bo *bo)
bo->map = NULL;
}
+static inline int
+gbm_dri_device_get_fd(struct gbm_dri_device *dri)
+{
+ return dri->fd;
+}
+
#endif
--
2.17.1

View file

@ -0,0 +1,364 @@
From 75b1c87bfdba318b06cbef887c415d74b945af88 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 20 May 2021 20:16:18 +0100
Subject: [PATCH 044/168] egl/null: add support for DRI_PRIME GPU selection
Add support for selecting the GPU to be used for rendering using
the DRI_PRIME environment variable. If a different GPU is selected,
a duplicate of the file descriptor for the original GPU/display is
preserved, which can be obtained by calling the getDisplayFD
function in the image loader extension.
This change includes code, in function dri2_null_try_device, to
optionally skip display devices that are not supported by a
particular DRI driver. This can be enabled by setting Meson build
option null-dri-driver-name. This feature is to prevent failure
on PC based test systems, that may have display and GPU hardware
other than that being tested.
---
meson.build | 4 +
meson_options.txt | 6 ++
src/egl/drivers/dri2/egl_dri2.c | 1 +
src/egl/drivers/dri2/platform_null.c | 135 +++++++++++++++++++--------
src/egl/meson.build | 5 +
5 files changed, 114 insertions(+), 37 deletions(-)
diff --git a/meson.build b/meson.build
index 3a6de3d5ce8..f4cbae5b0ab 100644
--- a/meson.build
+++ b/meson.build
@@ -380,6 +380,10 @@ with_platform_haiku = _platforms.contains('haiku')
with_platform_windows = _platforms.contains('windows')
with_platform_null = _platforms.contains('null')
+if with_platform_null
+ null_dri_driver_name = get_option('null-dri-driver-name')
+endif
+
with_glx = get_option('glx')
if with_glx == 'auto'
if with_platform_android
diff --git a/meson_options.txt b/meson_options.txt
index 43169974bff..0607fce2e2f 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -37,6 +37,12 @@ option(
],
description : 'the window system EGL assumes for EGL_DEFAULT_DISPLAY',
)
+option(
+ 'null-dri-driver-name',
+ type : 'string',
+ value : '',
+ description : 'For the null platform, ignore all dri drivers apart from this one. By default, no dri drivers are ignored.'
+)
option(
'android-stub',
type : 'boolean',
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 485ceeba9b4..80ba3647a9a 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1383,6 +1383,7 @@ dri2_display_destroy(_EGLDisplay *disp)
switch (disp->Platform) {
case _EGL_PLATFORM_DRM:
+ case _EGL_PLATFORM_NULL:
case _EGL_PLATFORM_WAYLAND:
case _EGL_PLATFORM_X11:
if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index c78e1fe0880..e2a138367f9 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -45,6 +45,7 @@
#include "egl_dri2.h"
#include "loader.h"
+#include "util/os_file.h"
#define NULL_CARD_MINOR_MAX 63U
@@ -1045,7 +1046,7 @@ swap_idle_get_target_frame(struct dri2_egl_surface *dri2_surf,
* current vblank by the number of intervals set at the time swapBuffer
* is called. For intervals of 1 or 0, we don't need a target frame.
*/
- err = display_get_vblank_sequence(dri2_dpy->fd, current_vblank_out);
+ err = display_get_vblank_sequence(dri2_dpy->fd_dpy, current_vblank_out);
if (err)
return err;
@@ -1095,7 +1096,7 @@ swap_vblank_state_transition(struct dri2_egl_surface *dri2_surf,
uint32_t flags = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
int err;
- err = display_request_vblank(dri2_dpy->fd, target_frame,
+ err = display_request_vblank(dri2_dpy->fd_dpy, target_frame,
flags, dri2_surf);
if (err) {
dri2_surf->swap_state = SWAP_ERROR;
@@ -1121,7 +1122,7 @@ swap_flip_state_transition(struct dri2_egl_surface *dri2_surf)
flags |= DRM_MODE_PAGE_FLIP_ASYNC;
}
- err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output,
+ err = display_output_flip(dri2_dpy->fd_dpy, &dri2_dpy->output,
dri2_surf->swap_data->fb_id, flags, dri2_surf);
if (err) {
dri2_surf->swap_state = SWAP_ERROR;
@@ -1141,7 +1142,7 @@ swap_poll_state_transition(struct dri2_egl_surface *dri2_surf)
int err;
/* dri2_surf->swap_state is being set inside the handler */
- err = drm_event_process(dri2_dpy->fd);
+ err = drm_event_process(dri2_dpy->fd_dpy);
if (err) {
dri2_surf->swap_state = SWAP_ERROR;
return err;
@@ -1296,7 +1297,7 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
handles[i] = (uint32_t) handle;
}
- return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height,
+ return !drmModeAddFB2WithModifiers(dri2_dpy->fd_dpy, width, height,
dri2_null_formats[format_idx].drm_format,
handles, pitches, offsets, modifiers,
fb_id_out, flags);
@@ -1486,7 +1487,7 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
dri2_surf->format = dri2_null_formats[format_idx].dri_image_format;
if (dri2_dpy->in_formats_enabled) {
- ret = in_formats_get_modifiers(dri2_dpy->fd,
+ ret = in_formats_get_modifiers(dri2_dpy->fd_dpy,
dri2_dpy->output.in_formats_id,
dri2_null_formats[format_idx].drm_format,
&dri2_dpy->output.modifiers);
@@ -1564,7 +1565,7 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config,
goto err_destroy_surface;
}
- err = display_output_modeset(dri2_dpy->fd, &dri2_dpy->output,
+ err = display_output_modeset(dri2_dpy->fd_dpy, &dri2_dpy->output,
dri2_surf->front_buffer.fb_id);
if (err) {
_eglError(EGL_BAD_NATIVE_WINDOW, "window set mode");
@@ -1678,11 +1679,11 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image);
if (dri2_surf->front_buffer.fb_id)
- drmModeRmFB(dri2_dpy->fd, dri2_surf->front_buffer.fb_id);
+ drmModeRmFB(dri2_dpy->fd_dpy, dri2_surf->front_buffer.fb_id);
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
if (dri2_surf->color_buffers[i].fb_id)
- drmModeRmFB(dri2_dpy->fd, dri2_surf->color_buffers[i].fb_id);
+ drmModeRmFB(dri2_dpy->fd_dpy, dri2_surf->color_buffers[i].fb_id);
if (dri2_surf->color_buffers[i].dri_image)
dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
}
@@ -1839,12 +1840,22 @@ dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
(void) loaderPrivate;
}
+static int
+dri2_null_get_display_fd(void *loaderPrivate)
+{
+ _EGLDisplay *disp = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ return dri2_dpy->fd_dpy;
+}
+
static const __DRIimageLoaderExtension image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 2 },
+ .base = { __DRI_IMAGE_LOADER, 5 },
.getBuffers = dri2_null_image_get_buffers,
.flushFrontBuffer = dri2_null_flush_front_buffer,
.getCapability = dri2_null_get_capability,
+ .getDisplayFD = dri2_null_get_display_fd,
};
static const __DRIextension *image_loader_extensions[] = {
@@ -1873,12 +1884,74 @@ dri2_null_device_is_kms(int fd)
return is_kms;
}
+static bool
+dri2_null_try_device(_EGLDisplay *disp)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ if (!dri2_null_device_is_kms(dri2_dpy->fd_dpy))
+ return false;
+
+#if defined(NULL_DRI_DRIVER_NAME)
+ /* Skip devices not handled by NULL_DRI_DRIVER_NAME */
+ {
+ char *driver_name = loader_get_driver_for_fd(dri2_dpy->fd_dpy);
+ bool skip = !driver_name || !!strcmp(driver_name, NULL_DRI_DRIVER_NAME);
+
+ free(driver_name);
+
+ if (skip)
+ return false;
+ }
+#endif
+
+ dri2_dpy->fd = os_dupfd_cloexec(dri2_dpy->fd_dpy);
+ if (dri2_dpy->fd < 0) {
+ _eglLog(_EGL_WARNING, "DRI2: failed to dup display FD");
+ dri2_dpy->fd = dri2_dpy->fd_dpy;
+ } else {
+ int fd_old;
+ bool is_different_gpu;
+
+ fd_old = dri2_dpy->fd;
+ dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd,
+ &is_different_gpu);
+ if (dri2_dpy->fd == fd_old) {
+ close (dri2_dpy->fd);
+ dri2_dpy->fd = dri2_dpy->fd_dpy;
+ }
+ }
+
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
+ if (!dri2_dpy->driver_name)
+ return false;
+
+ if (dri2_load_driver_dri3(disp)) {
+ _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false);
+ if (!dev) {
+ dlclose(dri2_dpy->driver);
+ _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice");
+ } else {
+ dri2_dpy->loader_extensions = image_loader_extensions;
+ dri2_dpy->own_device = 1;
+ disp->Device = dev;
+ return true;
+ }
+ }
+
+ free(dri2_dpy->driver_name);
+ dri2_dpy->driver_name = NULL;
+
+ return false;
+}
+
static bool
dri2_null_probe_device(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
dri2_dpy->fd = -1;
+ dri2_dpy->fd_dpy = -1;
for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) {
char *card_path;
@@ -1886,32 +1959,20 @@ dri2_null_probe_device(_EGLDisplay *disp)
if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, i) < 0)
continue;
- dri2_dpy->fd = loader_open_device(card_path);
+ dri2_dpy->fd_dpy = loader_open_device(card_path);
free(card_path);
- if (dri2_dpy->fd < 0)
+ if (dri2_dpy->fd_dpy < 0)
continue;
- if (dri2_null_device_is_kms(dri2_dpy->fd)) {
- dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
- if (dri2_dpy->driver_name) {
- if (dri2_load_driver_dri3(disp)) {
- _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false);
- if (!dev) {
- dlclose(dri2_dpy->driver);
- _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice");
- } else {
- dri2_dpy->loader_extensions = image_loader_extensions;
- dri2_dpy->own_device = 1;
- disp->Device = dev;
- return true;
- }
- }
- free(dri2_dpy->driver_name);
- dri2_dpy->driver_name = NULL;
- }
- }
+ if (dri2_null_try_device(disp))
+ return true;
+
+ close(dri2_dpy->fd_dpy);
+
+ if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy)
+ close(dri2_dpy->fd);
- close(dri2_dpy->fd);
+ dri2_dpy->fd_dpy = -1;
dri2_dpy->fd = -1;
}
@@ -1972,7 +2033,7 @@ dri2_null_setup_swap_interval(_EGLDisplay *disp)
dri2_setup_swap_interval(disp, swap_max_interval);
- err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
+ err = drmGetCap(dri2_dpy->fd_dpy, DRM_CAP_ASYNC_PAGE_FLIP, &value);
if (err || value == 0) {
/* DRM/KMS does not support async page flip. In order to support
@@ -2020,7 +2081,7 @@ dri2_initialize_null(_EGLDisplay *disp)
* modesetting if not. If this succeeds then universal planes will also have
* been enabled.
*/
- err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_ATOMIC, 1);
+ err = drmSetClientCap(dri2_dpy->fd_dpy, DRM_CLIENT_CAP_ATOMIC, 1);
dri2_dpy->atomic_enabled = !err;
if (!dri2_dpy->atomic_enabled) {
@@ -2028,7 +2089,7 @@ dri2_initialize_null(_EGLDisplay *disp)
* Enable universal planes so that we can get the pixel formats for the
* primary plane
*/
- err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+ err = drmSetClientCap(dri2_dpy->fd_dpy, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
if (err) {
_eglError(EGL_NOT_INITIALIZED, "failed to enable universal planes");
goto cleanup;
@@ -2064,7 +2125,7 @@ dri2_initialize_null(_EGLDisplay *disp)
dri2_dpy->image->createImageWithModifiers;
}
- if (!display_output_init(dri2_dpy->fd, &dri2_dpy->output,
+ if (!display_output_init(dri2_dpy->fd_dpy, &dri2_dpy->output,
dri2_dpy->atomic_enabled,
prefer_in_formats,
&dri2_dpy->in_formats_enabled)) {
@@ -2098,7 +2159,7 @@ dri2_teardown_null(struct dri2_egl_display *dri2_dpy)
drmModeAtomicFree(dri2_dpy->output.atomic_state);
if (dri2_dpy->output.mode_blob_id)
- drmModeDestroyPropertyBlob(dri2_dpy->fd, dri2_dpy->output.mode_blob_id);
+ drmModeDestroyPropertyBlob(dri2_dpy->fd_dpy, dri2_dpy->output.mode_blob_id);
if (dri2_dpy->output.plane_prop_res) {
for (unsigned i = 0; dri2_dpy->output.plane_prop_res[i]; i++)
diff --git a/src/egl/meson.build b/src/egl/meson.build
index b20d85dc19f..88514d7dcb2 100644
--- a/src/egl/meson.build
+++ b/src/egl/meson.build
@@ -153,6 +153,11 @@ elif with_platform_windows
link_for_egl += libgallium_wgl
endif
if with_platform_null
+ if null_dri_driver_name != ''
+ c_args_for_egl += [
+ '-DNULL_DRI_DRIVER_NAME="@0@"'.format(null_dri_driver_name),
+ ]
+ endif
files_egl += files('drivers/dri2/platform_null.c')
incs_for_egl += [inc_loader]
deps_for_egl += dep_libdrm
--
2.17.1

View file

@ -0,0 +1,120 @@
From 5ff6d94aeff451aea33268fc13e605981515e605 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 28 Jun 2021 16:36:15 +0100
Subject: [PATCH 045/168] egl/null: introduce NULL_DRM_DISPLAY
Introduce the NULL_DRM_DISPLAY environment variable, which allows
a particular DRM display to be selected, rather than the first
suitable DRM device found.
To select a particular display, NULL_DRM_DISPLAY should be set to
the card number (i.e. minor number) of the DRM device representing
the display. For example, NULL_DRM_DISPLAY=2 will select
/dev/dri/card2.
---
src/egl/drivers/dri2/platform_null.c | 65 ++++++++++++++++++++--------
1 file changed, 46 insertions(+), 19 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index e2a138367f9..7e631e0b61d 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -1889,6 +1889,8 @@ dri2_null_try_device(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ dri2_dpy->fd = -1;
+
if (!dri2_null_device_is_kms(dri2_dpy->fd_dpy))
return false;
@@ -1946,34 +1948,56 @@ dri2_null_try_device(_EGLDisplay *disp)
}
static bool
-dri2_null_probe_device(_EGLDisplay *disp)
+dri2_null_probe_device(_EGLDisplay *disp, unsigned minor)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ char *card_path;
- dri2_dpy->fd = -1;
- dri2_dpy->fd_dpy = -1;
+ if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, minor) < 0)
+ goto cleanup;
- for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) {
- char *card_path;
+ dri2_dpy->fd_dpy = loader_open_device(card_path);
+ free(card_path);
+ if (dri2_dpy->fd_dpy < 0)
+ goto cleanup;
- if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, i) < 0)
- continue;
+ if (dri2_null_try_device(disp))
+ return true;
- dri2_dpy->fd_dpy = loader_open_device(card_path);
- free(card_path);
- if (dri2_dpy->fd_dpy < 0)
- continue;
+ close(dri2_dpy->fd_dpy);
- if (dri2_null_try_device(disp))
- return true;
+ if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy)
+ close(dri2_dpy->fd);
- close(dri2_dpy->fd_dpy);
+cleanup:
+ dri2_dpy->fd_dpy = -1;
+ dri2_dpy->fd = -1;
- if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy)
- close(dri2_dpy->fd);
+ return false;
+}
+
+static bool
+dri2_null_probe_devices(_EGLDisplay *disp)
+{
+ const char *null_drm_display = getenv("NULL_DRM_DISPLAY");
+
+ if (null_drm_display) {
+ char *endptr;
+ long val = strtol(null_drm_display, &endptr, 10);
- dri2_dpy->fd_dpy = -1;
- dri2_dpy->fd = -1;
+ if (endptr != null_drm_display && !*endptr &&
+ val >= 0 && val <= NULL_CARD_MINOR_MAX) {
+ if (dri2_null_probe_device(disp, (unsigned)val))
+ return true;
+ } else {
+ _eglLog(_EGL_FATAL, "NULL_DRM_DISPLAY is invalid: %s",
+ null_drm_display);
+ }
+ } else {
+ for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) {
+ if (dri2_null_probe_device(disp, i))
+ return true;
+ }
}
return false;
@@ -2071,7 +2095,10 @@ dri2_initialize_null(_EGLDisplay *disp)
disp->DriverData = (void *) dri2_dpy;
- if (!dri2_null_probe_device(disp)) {
+ dri2_dpy->fd_dpy = -1;
+ dri2_dpy->fd = -1;
+
+ if (!dri2_null_probe_devices(disp)) {
_eglError(EGL_NOT_INITIALIZED, "failed to load driver");
goto cleanup;
}
--
2.17.1

View file

@ -0,0 +1,28 @@
From 6189dd1b7120792a131dd214f9383540aafbb45b Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 21 Jun 2021 17:05:17 +0100
Subject: [PATCH 046/168] vulkan/wsi: check the DRI3 and Present XCB reply
pointers
Check that the DRI3 and Present version replies are not NULL
before accessing the version fields.
---
src/vulkan/wsi/wsi_common_x11.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index a3c4538366f..535b6d10e0b 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -285,7 +285,7 @@ wsi_x11_connection_create(struct wsi_device *wsi_dev,
ver_cookie = xcb_present_query_version(conn, 1, 2);
ver_reply = xcb_present_query_version_reply(conn, ver_cookie, NULL);
- has_present_v1_2 =
+ has_present_v1_2 = ver_reply != NULL &&
(ver_reply->major_version > 1 || ver_reply->minor_version >= 2);
free(ver_reply);
}
--
2.17.1

View file

@ -0,0 +1,757 @@
From 4259a670e2c28a13cbc56f6f747156ebcfa0582b Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 17 Jun 2021 17:17:07 +0100
Subject: [PATCH 047/168] vulkan/wsi: make the display FD available
Pass the display FD to the Vulkan image create and memory
allocation functions when allocating swapchain images.
The wl_drm interface code has been partially restored, in order
to obtain the display FD from the compositor.
---
src/vulkan/wsi/meson.build | 2 +
src/vulkan/wsi/wsi_common.c | 41 +++++++--
src/vulkan/wsi/wsi_common.h | 14 +++
src/vulkan/wsi/wsi_common_display.c | 4 +-
src/vulkan/wsi/wsi_common_drm.c | 23 ++++-
src/vulkan/wsi/wsi_common_private.h | 12 ++-
src/vulkan/wsi/wsi_common_wayland.c | 134 +++++++++++++++++++++++++---
src/vulkan/wsi/wsi_common_win32.c | 4 +-
src/vulkan/wsi/wsi_common_x11.c | 26 +++++-
9 files changed, 229 insertions(+), 31 deletions(-)
diff --git a/src/vulkan/wsi/meson.build b/src/vulkan/wsi/meson.build
index a92c7f3e5eb..68d53d51a04 100644
--- a/src/vulkan/wsi/meson.build
+++ b/src/vulkan/wsi/meson.build
@@ -31,6 +31,8 @@ endif
if with_platform_wayland
files_vulkan_wsi += files('wsi_common_wayland.c')
files_vulkan_wsi += [
+ wayland_drm_client_protocol_h,
+ wayland_drm_protocol_c,
linux_dmabuf_unstable_v1_client_protocol_h,
linux_dmabuf_unstable_v1_protocol_c,
]
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
index b2974fad7ce..6ca7c767b26 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
@@ -305,6 +305,7 @@ static VkResult
configure_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const struct wsi_base_image_params *params,
+ UNUSED int display_fd,
struct wsi_image_info *info)
{
switch (params->image_type) {
@@ -317,7 +318,8 @@ configure_image(const struct wsi_swapchain *chain,
case WSI_IMAGE_TYPE_DRM: {
const struct wsi_drm_image_params *drm_params =
container_of(params, const struct wsi_drm_image_params, base);
- return wsi_drm_configure_image(chain, pCreateInfo, drm_params, info);
+ return wsi_drm_configure_image(chain, pCreateInfo, drm_params,
+ display_fd, info);
}
#endif
default:
@@ -331,7 +333,8 @@ wsi_swapchain_init(const struct wsi_device *wsi,
VkDevice _device,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const struct wsi_base_image_params *image_params,
- const VkAllocationCallbacks *pAllocator)
+ const VkAllocationCallbacks *pAllocator,
+ int display_fd)
{
VK_FROM_HANDLE(vk_device, device, _device);
VkResult result;
@@ -377,7 +380,7 @@ wsi_swapchain_init(const struct wsi_device *wsi,
}
result = configure_image(chain, pCreateInfo, image_params,
- &chain->image_info);
+ display_fd, &chain->image_info);
if (result != VK_SUCCESS)
goto fail;
@@ -476,6 +479,7 @@ VkResult
wsi_configure_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
VkExternalMemoryHandleTypeFlags handle_types,
+ int display_fd,
struct wsi_image_info *info)
{
memset(info, 0, sizeof(*info));
@@ -534,6 +538,12 @@ wsi_configure_image(const struct wsi_swapchain *chain,
};
__vk_append_struct(&info->create, &info->wsi);
+ info->wsi2 = (struct wsi_image_create_info2) {
+ .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO2_MESA,
+ .display_fd = display_fd,
+ };
+ __vk_append_struct(&info->create, &info->wsi2);
+
if (pCreateInfo->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
info->create.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
@@ -599,6 +609,7 @@ wsi_destroy_image_info(const struct wsi_swapchain *chain,
VkResult
wsi_create_image(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
+ int display_fd,
struct wsi_image *image)
{
const struct wsi_device *wsi = chain->wsi;
@@ -615,7 +626,7 @@ wsi_create_image(const struct wsi_swapchain *chain,
if (result != VK_SUCCESS)
goto fail;
- result = info->create_mem(chain, info, image);
+ result = info->create_mem(chain, info, display_fd, image);
if (result != VK_SUCCESS)
goto fail;
@@ -1420,7 +1431,8 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image,
VkExternalMemoryHandleTypeFlags handle_types,
- bool implicit_sync)
+ bool implicit_sync,
+ int display_fd)
{
const struct wsi_device *wsi = chain->wsi;
VkResult result;
@@ -1484,6 +1496,13 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
.handleTypes = handle_types,
};
__vk_append_struct(&buf_mem_info, &memory_export_info);
+
+ struct wsi_memory_allocate_info2 memory_wsi_info2 = {
+ .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA,
+ .pNext = &memory_wsi_info,
+ .display_fd = display_fd,
+ };
+ __vk_append_struct(&buf_mem_info, &memory_wsi_info2);
}
result = wsi->AllocateMemory(chain->device, &buf_mem_info,
@@ -1630,6 +1649,7 @@ VkResult
wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
uint32_t stride_align, uint32_t size_align,
+ int display_fd,
struct wsi_image_info *info)
{
const struct wsi_device *wsi = chain->wsi;
@@ -1638,7 +1658,8 @@ wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
assert(util_is_power_of_two_nonzero(size_align));
VkResult result = wsi_configure_image(chain, pCreateInfo,
- 0 /* handle_types */, info);
+ 0 /* handle_types */,
+ display_fd, info);
if (result != VK_SUCCESS)
return result;
@@ -1667,6 +1688,7 @@ wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
static VkResult
wsi_create_cpu_linear_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
+ int display_fd,
struct wsi_image *image)
{
const struct wsi_device *wsi = chain->wsi;
@@ -1732,12 +1754,14 @@ wsi_create_cpu_linear_image_mem(const struct wsi_swapchain *chain,
static VkResult
wsi_create_cpu_buffer_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
+ int display_fd,
struct wsi_image *image)
{
VkResult result;
result = wsi_create_buffer_image_mem(chain, info, image, 0,
- false /* implicit_sync */);
+ false /* implicit_sync */,
+ display_fd);
if (result != VK_SUCCESS)
return result;
@@ -1778,6 +1802,7 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain,
VkResult result = wsi_configure_buffer_image(chain, pCreateInfo,
1 /* stride_align */,
1 /* size_align */,
+ -1,
info);
if (result != VK_SUCCESS)
return result;
@@ -1787,7 +1812,7 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain,
info->create_mem = wsi_create_cpu_buffer_image_mem;
} else {
VkResult result = wsi_configure_image(chain, pCreateInfo,
- handle_types, info);
+ handle_types, -1, info);
if (result != VK_SUCCESS)
return result;
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index 886bac9f800..c8b52339843 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -50,6 +50,8 @@ extern const struct vk_device_entrypoint_table wsi_device_entrypoints;
#define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA (VkStructureType)1000001003
#define VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA (VkStructureType)1000001005
#define VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA (VkStructureType)1000001006
+#define VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO2_MESA (VkStructureType)1000001007
+#define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA (VkStructureType)1000001008
/* This is always chained to VkImageCreateInfo when a wsi image is created.
* It indicates that the image can be transitioned to/from
@@ -86,6 +88,18 @@ struct wsi_memory_signal_submit_info {
VkDeviceMemory memory;
};
+struct wsi_image_create_info2 {
+ VkStructureType sType;
+ const void *pNext;
+ int display_fd;
+};
+
+struct wsi_memory_allocate_info2 {
+ VkStructureType sType;
+ const void *pNext;
+ int display_fd;
+};
+
struct wsi_interface;
struct driOptionCache;
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
index 0e5d27278b1..b9e6f18c8ba 100644
--- a/src/vulkan/wsi/wsi_common_display.c
+++ b/src/vulkan/wsi/wsi_common_display.c
@@ -1097,7 +1097,7 @@ wsi_display_image_init(VkDevice device_h,
return VK_ERROR_DEVICE_LOST;
VkResult result = wsi_create_image(&chain->base, &chain->base.image_info,
- &image->base);
+ wsi->fd, &image->base);
if (result != VK_SUCCESS)
return result;
@@ -1957,7 +1957,7 @@ wsi_display_surface_create_swapchain(
VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device,
create_info, &image_params.base,
- allocator);
+ allocator, wsi->fd);
if (result != VK_SUCCESS) {
vk_free(allocator, chain);
return result;
diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c
index 728e45152c5..a94be2aeb42 100644
--- a/src/vulkan/wsi/wsi_common_drm.c
+++ b/src/vulkan/wsi/wsi_common_drm.c
@@ -315,6 +315,7 @@ get_modifier_props(const struct wsi_image_info *info, uint64_t modifier)
static VkResult
wsi_create_native_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
+ int display_fd,
struct wsi_image *image);
static VkResult
@@ -323,6 +324,7 @@ wsi_configure_native_image(const struct wsi_swapchain *chain,
uint32_t num_modifier_lists,
const uint32_t *num_modifiers,
const uint64_t *const *modifiers,
+ int display_fd,
struct wsi_image_info *info)
{
const struct wsi_device *wsi = chain->wsi;
@@ -330,7 +332,8 @@ wsi_configure_native_image(const struct wsi_swapchain *chain,
VkExternalMemoryHandleTypeFlags handle_type =
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
- VkResult result = wsi_configure_image(chain, pCreateInfo, handle_type, info);
+ VkResult result = wsi_configure_image(chain, pCreateInfo, handle_type,
+ display_fd, info);
if (result != VK_SUCCESS)
return result;
@@ -467,6 +470,7 @@ fail_oom:
static VkResult
wsi_create_native_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
+ int display_fd,
struct wsi_image *image)
{
const struct wsi_device *wsi = chain->wsi;
@@ -480,9 +484,14 @@ wsi_create_native_image_mem(const struct wsi_swapchain *chain,
.pNext = NULL,
.implicit_sync = true,
};
+ const struct wsi_memory_allocate_info2 memory_wsi_info2 = {
+ .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA,
+ .pNext = &memory_wsi_info,
+ .display_fd = display_fd,
+ };
const VkExportMemoryAllocateInfo memory_export_info = {
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
- .pNext = &memory_wsi_info,
+ .pNext = &memory_wsi_info2,
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
};
const VkMemoryDedicatedAllocateInfo memory_dedicated_info = {
@@ -570,13 +579,14 @@ wsi_create_native_image_mem(const struct wsi_swapchain *chain,
static VkResult
wsi_create_prime_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
+ int display_fd,
struct wsi_image *image)
{
const struct wsi_device *wsi = chain->wsi;
VkResult result =
wsi_create_buffer_image_mem(chain, info, image,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
- true);
+ true, display_fd);
if (result != VK_SUCCESS)
return result;
@@ -602,11 +612,13 @@ wsi_configure_prime_image(UNUSED const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
bool use_modifier,
wsi_memory_type_select_cb select_buffer_memory_type,
+ int display_fd,
struct wsi_image_info *info)
{
VkResult result =
wsi_configure_buffer_image(chain, pCreateInfo,
WSI_PRIME_LINEAR_STRIDE_ALIGN, 4096,
+ display_fd,
info);
if (result != VK_SUCCESS)
return result;
@@ -637,6 +649,7 @@ VkResult
wsi_drm_configure_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const struct wsi_drm_image_params *params,
+ int display_fd,
struct wsi_image_info *info)
{
assert(params->base.image_type == WSI_IMAGE_TYPE_DRM);
@@ -647,12 +660,14 @@ wsi_drm_configure_image(const struct wsi_swapchain *chain,
params->same_gpu ? wsi_select_device_memory_type :
prime_select_buffer_memory_type;
return wsi_configure_prime_image(chain, pCreateInfo, use_modifier,
- select_buffer_memory_type, info);
+ select_buffer_memory_type,
+ display_fd, info);
} else {
return wsi_configure_native_image(chain, pCreateInfo,
params->num_modifier_lists,
params->num_modifiers,
params->modifiers,
+ display_fd,
info);
}
}
diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h
index fe3e85556b8..868fdf968e4 100644
--- a/src/vulkan/wsi/wsi_common_private.h
+++ b/src/vulkan/wsi/wsi_common_private.h
@@ -69,6 +69,7 @@ typedef uint32_t (*wsi_memory_type_select_cb)(const struct wsi_device *wsi,
struct wsi_image_info {
VkImageCreateInfo create;
struct wsi_image_create_info wsi;
+ struct wsi_image_create_info2 wsi2;
VkExternalMemoryImageCreateInfo ext_mem;
VkImageFormatListCreateInfo format_list;
VkImageDrmFormatModifierListCreateInfoEXT drm_mod_list;
@@ -94,6 +95,7 @@ struct wsi_image_info {
VkResult (*create_mem)(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
+ int display_fd,
struct wsi_image *image);
VkResult (*finish_create)(const struct wsi_swapchain *chain,
@@ -178,7 +180,8 @@ wsi_swapchain_init(const struct wsi_device *wsi,
VkDevice device,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const struct wsi_base_image_params *image_params,
- const VkAllocationCallbacks *pAllocator);
+ const VkAllocationCallbacks *pAllocator,
+ int display_fd);
enum VkPresentModeKHR
wsi_swapchain_get_present_mode(struct wsi_device *wsi,
@@ -203,6 +206,7 @@ VkResult
wsi_drm_configure_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const struct wsi_drm_image_params *params,
+ int display_fd,
struct wsi_image_info *info);
bool
@@ -220,7 +224,8 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image,
VkExternalMemoryHandleTypeFlags handle_types,
- bool implicit_sync);
+ bool implicit_sync,
+ int display_fd);
VkResult
wsi_finish_create_buffer_image(const struct wsi_swapchain *chain,
@@ -231,12 +236,14 @@ VkResult
wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
uint32_t stride_align, uint32_t size_align,
+ int display_fd,
struct wsi_image_info *info);
VkResult
wsi_configure_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
VkExternalMemoryHandleTypeFlags handle_types,
+ int display_fd,
struct wsi_image_info *info);
void
wsi_destroy_image_info(const struct wsi_swapchain *chain,
@@ -244,6 +251,7 @@ wsi_destroy_image_info(const struct wsi_swapchain *chain,
VkResult
wsi_create_image(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
+ int display_fd,
struct wsi_image *image);
void
wsi_image_init(struct wsi_image *image);
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index 70b00429972..b1e5ea8bdfd 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -33,6 +33,8 @@
#include <poll.h>
#include <sys/mman.h>
#include <sys/types.h>
+#include <fcntl.h>
+#include <xf86drm.h>
#include "drm-uapi/drm_fourcc.h"
@@ -95,6 +97,7 @@ struct wsi_wl_display {
struct wl_event_queue *queue;
struct wl_shm *wl_shm;
+ struct wl_drm *wl_drm;
struct zwp_linux_dmabuf_v1 *wl_dmabuf;
struct zwp_linux_dmabuf_feedback_v1 *wl_dmabuf_feedback;
@@ -104,6 +107,8 @@ struct wsi_wl_display {
/* Formats populated by zwp_linux_dmabuf_v1 or wl_shm interfaces */
struct u_vector formats;
+ int fd;
+ bool authenticated;
bool sw;
@@ -530,6 +535,79 @@ wl_shm_format_for_vk_format(VkFormat vk_format, bool alpha)
}
}
+static int
+open_display_device(const char *name)
+{
+ int fd;
+
+#ifdef O_CLOEXEC
+ fd = open(name, O_RDWR | O_CLOEXEC);
+ if (fd != -1 || errno != EINVAL) {
+ return fd;
+ }
+#endif
+
+ fd = open(name, O_RDWR);
+ if (fd != -1) {
+ long flags = fcntl(fd, F_GETFD);
+
+ if (flags != -1) {
+ if (!fcntl(fd, F_SETFD, flags | FD_CLOEXEC))
+ return fd;
+ }
+ close (fd);
+ }
+
+ return -1;
+}
+
+static void
+drm_handle_device(void *data, struct wl_drm *drm, const char *name)
+{
+ struct wsi_wl_display *display = data;
+ const int fd = open_display_device(name);
+
+ if (fd != -1) {
+ if (drmGetNodeTypeFromFd(fd) != DRM_NODE_RENDER) {
+ drm_magic_t magic;
+
+ if (drmGetMagic(fd, &magic)) {
+ close(fd);
+ return;
+ }
+ wl_drm_authenticate(drm, magic);
+ } else {
+ display->authenticated = true;
+ }
+ display->fd = fd;
+ }
+}
+
+static void
+drm_handle_format(void *data, struct wl_drm *drm, uint32_t wl_format)
+{
+}
+
+static void
+drm_handle_authenticated(void *data, struct wl_drm *drm)
+{
+ struct wsi_wl_display *display = data;
+
+ display->authenticated = true;
+}
+
+static void
+drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t capabilities)
+{
+}
+
+static const struct wl_drm_listener drm_listener = {
+ drm_handle_device,
+ drm_handle_format,
+ drm_handle_authenticated,
+ drm_handle_capabilities,
+};
+
static void
dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
uint32_t format)
@@ -741,6 +819,15 @@ registry_handle_global(void *data, struct wl_registry *registry,
return;
}
+ if (strcmp(interface, "wl_drm") == 0) {
+ assert(display->wl_drm == NULL);
+ assert(version >= 2);
+
+ display->wl_drm =
+ wl_registry_bind(registry, name, &wl_drm_interface, 2);
+ wl_drm_add_listener(display->drm.wl_drm, &drm_listener, display);
+ }
+
if (strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0 && version >= 3) {
display->wl_dmabuf =
wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface,
@@ -769,12 +856,17 @@ wsi_wl_display_finish(struct wsi_wl_display *display)
u_vector_finish(&display->formats);
if (display->wl_shm)
wl_shm_destroy(display->wl_shm);
+ if (display->wl_drm)
+ wl_drm_destroy(display->wl_drm);
if (display->wl_dmabuf)
zwp_linux_dmabuf_v1_destroy(display->wl_dmabuf);
if (display->wl_display_wrapper)
wl_proxy_wrapper_destroy(display->wl_display_wrapper);
if (display->queue)
wl_event_queue_destroy(display->queue);
+
+ if (display->fd != -1)
+ close(display->fd);
}
static VkResult
@@ -792,6 +884,7 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
display->wsi_wl = wsi_wl;
display->wl_display = wl_display;
display->sw = sw;
+ display->fd = -1;
display->queue = wl_display_create_queue(wl_display);
if (!display->queue) {
@@ -817,17 +910,13 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
wl_registry_add_listener(registry, &registry_listener, display);
- /* Round-trip to get wl_shm and zwp_linux_dmabuf_v1 globals */
+ /* Round-trip to get wl_shm, wl_drm and zwp_linux_dmabuf_v1 globals */
wl_display_roundtrip_queue(display->wl_display, display->queue);
if (!display->wl_dmabuf && !display->wl_shm) {
result = VK_ERROR_SURFACE_LOST_KHR;
goto fail_registry;
}
- /* Caller doesn't expect us to query formats/modifiers, so return */
- if (!get_format_list)
- goto out;
-
/* Default assumption */
display->same_gpu = true;
@@ -858,14 +947,38 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
}
}
- /* Round-trip again to get formats and modifiers */
- wl_display_roundtrip_queue(display->wl_display, display->queue);
+ if (display->wl_dmabuf && !display->wl_drm) {
+ result = VK_ERROR_SURFACE_LOST_KHR;
+ goto fail_registry;
+ }
+
+ /* Round-trip to get display FD, formats and modifiers */
+ if (display->wl_drm || get_format_list)
+ wl_display_roundtrip_queue(display->wl_display, display->queue);
+
+ if (display->wl_drm && display->fd == -1) {
+ result = VK_ERROR_SURFACE_LOST_KHR;
+ goto fail_registry;
+ }
+
+ if (display->wl_drm) {
+ wl_display_roundtrip_queue(display->wl_display, display->queue);
+
+ if (!display->authenticated) {
+ result = VK_ERROR_SURFACE_LOST_KHR;
+ goto fail_registry;
+ }
+ }
+
+ /* Caller doesn't expect us to query formats/modifiers, so return */
+ if (!get_format_list)
+ goto out;
if (wsi_wl->wsi->force_bgra8_unorm_first) {
/* Find BGRA8_UNORM in the list and swap it to the first position if we
* can find it. Some apps get confused if SRGB is first in the list.
*/
- struct wsi_wl_format *first_fmt = u_vector_head(&display->formats);
+ struct wsi_wl_format *first_fmt = u_vector_tail(&display->formats);
struct wsi_wl_format *f, tmp_fmt;
f = find_format(&display->formats, VK_FORMAT_B8G8R8A8_UNORM);
if (f) {
@@ -1648,7 +1761,7 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain,
VkResult result;
result = wsi_create_image(&chain->base, &chain->base.image_info,
- &image->base);
+ display->fd, &image->base);
if (result != VK_SUCCESS)
return result;
@@ -1857,7 +1970,8 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
}
result = wsi_swapchain_init(wsi_device, &chain->base, device,
- pCreateInfo, image_params, pAllocator);
+ pCreateInfo, image_params, pAllocator,
+ chain->wsi_wl_surface->display->fd);
if (result != VK_SUCCESS) {
vk_free(pAllocator, chain);
return result;
diff --git a/src/vulkan/wsi/wsi_common_win32.c b/src/vulkan/wsi/wsi_common_win32.c
index bef81028bde..7d16144f3ed 100644
--- a/src/vulkan/wsi/wsi_common_win32.c
+++ b/src/vulkan/wsi/wsi_common_win32.c
@@ -310,7 +310,7 @@ wsi_win32_image_init(VkDevice device_h,
{
assert(chain->base.use_buffer_blit);
VkResult result = wsi_create_image(&chain->base, &chain->base.image_info,
- &image->base);
+ -1, &image->base);
if (result != VK_SUCCESS)
return result;
@@ -454,7 +454,7 @@ wsi_win32_surface_create_swapchain(
VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device,
create_info, &image_params.base,
- allocator);
+ allocator, -1);
if (result != VK_SUCCESS) {
vk_free(allocator, chain);
return result;
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 535b6d10e0b..2a988b6d2a8 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -1660,6 +1660,7 @@ static VkResult
x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks* pAllocator,
+ int display_fd,
struct x11_image *image)
{
xcb_void_cookie_t cookie;
@@ -1668,7 +1669,7 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
int fence_fd;
result = wsi_create_image(&chain->base, &chain->base.image_info,
- &image->base);
+ display_fd, &image->base);
if (result != VK_SUCCESS)
return result;
@@ -2048,8 +2049,19 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
image_params = &drm_image_params.base;
}
+ int display_fd;
+ if (wsi_device->sw) {
+ display_fd = -1;
+ } else {
+ xcb_screen_iterator_t screen_iter =
+ xcb_setup_roots_iterator(xcb_get_setup(conn));
+ xcb_screen_t *screen = screen_iter.data;
+
+ display_fd = wsi_dri3_open(conn, screen->root, None);
+ }
+
result = wsi_swapchain_init(wsi_device, &chain->base, device, pCreateInfo,
- image_params, pAllocator);
+ image_params, pAllocator, display_fd);
for (int i = 0; i < ARRAY_SIZE(modifiers); i++)
vk_free(pAllocator, modifiers[i]);
@@ -2140,11 +2152,16 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
uint32_t image = 0;
for (; image < chain->base.image_count; image++) {
result = x11_image_init(device, chain, pCreateInfo, pAllocator,
- &chain->images[image]);
+ display_fd, &chain->images[image]);
if (result != VK_SUCCESS)
goto fail_init_images;
}
+ if (display_fd >= 0) {
+ close(display_fd);
+ display_fd = -1;
+ }
+
/* Initialize queues for images in our swapchain. Possible queues are:
* - Present queue: for images sent to the X server but not yet presented.
* - Acquire queue: for images already presented but not yet released by the
@@ -2222,6 +2239,9 @@ fail_register:
fail_alloc:
vk_free(pAllocator, chain);
+ if (display_fd >= 0)
+ close(display_fd);
+
return result;
}
--
2.17.1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,80 @@
From eefa4483028dab0bd5b4e21b4179b151696ca4da Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Fri, 30 Jul 2021 15:34:13 +0100
Subject: [PATCH 049/168] vulkan/wsi: Disable use of VK_EXT_pci_bus_info
The VK_EXT_pci_bus_info related code has been wrapped in
VULKAN_WSI_USE_PCI_BUS_INFO, effectively disabling it.
Not all platforms support the VK_EXT_pci_bus_info extension.
A better fix might be to pass another parameter to wsi_device_init,
to indicate that the device is a PCI one.
---
src/vulkan/wsi/wsi_common.c | 6 ++++++
src/vulkan/wsi/wsi_common.h | 3 +++
src/vulkan/wsi/wsi_common_drm.c | 4 ++++
3 files changed, 13 insertions(+)
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
index 815ecc07c09..65049bd5f06 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
@@ -92,12 +92,18 @@ wsi_device_init2(struct wsi_device *wsi,
wsi->drm_info.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
+#if defined(VULKAN_WSI_USE_PCI_BUS_INFO)
wsi->pci_bus_info.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT;
wsi->pci_bus_info.pNext = &wsi->drm_info;
+#endif
VkPhysicalDeviceProperties2 pdp2 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
+#if defined(VULKAN_WSI_USE_PCI_BUS_INFO)
.pNext = &wsi->pci_bus_info,
+#else
+ .pNext = &wsi->drm_info,
+#endif
};
GetPhysicalDeviceProperties2(pdevice, &pdp2);
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index 0f5790b2213..aec1021113e 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -115,7 +115,10 @@ struct wsi_device {
uint32_t queue_family_count;
VkPhysicalDeviceDrmPropertiesEXT drm_info;
+
+#if defined(VULKAN_WSI_USE_PCI_BUS_INFO)
VkPhysicalDevicePCIBusInfoPropertiesEXT pci_bus_info;
+#endif
VkExternalSemaphoreHandleTypeFlags semaphore_export_handle_types;
diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c
index a94be2aeb42..0a7887368fc 100644
--- a/src/vulkan/wsi/wsi_common_drm.c
+++ b/src/vulkan/wsi/wsi_common_drm.c
@@ -275,6 +275,7 @@ wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd)
if (ret)
return false;
+#if defined(VULKAN_WSI_USE_PCI_BUS_INFO)
bool match = false;
switch (fd_device->bustype) {
case DRM_BUS_PCI:
@@ -287,6 +288,9 @@ wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd)
default:
break;
}
+#else
+ const bool match = true;
+#endif
drmFreeDevice(&fd_device);
--
2.17.1

View file

@ -0,0 +1,34 @@
From 367580365944010cb0b605a03d750dcfc0dd7223 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 2 Aug 2021 16:29:36 +0100
Subject: [PATCH 050/168] vulkan/wsi: default to force_bgra8_unorm_first true
If VULKAN_WSI_BGRA8_SNORM_FIRST is not defined, default to
force_bgra8_unorm_first true.
This brings Mesa WSI into line with IMG WSI with regards to the
VK_FORMAT_B8G8R8A8_UNORM and VK_FORMAT_B8G8R8A8_SRGB formats.
With this change, the IMG Vulkan unit test, vkbonjour, will default
to VK_FORMAT_B8G8R8A8_UNORM rather than VK_FORMAT_B8G8R8A8_SRGB.
---
src/vulkan/wsi/wsi_common.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
index 65049bd5f06..389117ceb2e 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
@@ -237,6 +237,10 @@ wsi_device_init2(struct wsi_device *wsi,
driQueryOptionb(dri_options, "vk_wsi_force_bgra8_unorm_first");
}
}
+#if !defined(VULKAN_WSI_BGRA8_SNORM_FIRST)
+ else
+ wsi->force_bgra8_unorm_first = true;
+#endif
return VK_SUCCESS;
#if defined(VK_USE_PLATFORM_XCB_KHR) || \
--
2.17.1

View file

@ -0,0 +1,27 @@
From ce0bc276a1674ea1573df4b522ac3b70154c7c92 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 3 Aug 2021 15:44:57 +0100
Subject: [PATCH 051/168] vulkan/wsi: enable additional formats for Display
Add VK_FORMAT_R5G6B5_UNORM_PACK16.
This is for compatibility with IMG WSI.
---
src/vulkan/wsi/wsi_common_display.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
index 7dd6af7c287..e0232e08e1d 100644
--- a/src/vulkan/wsi/wsi_common_display.c
+++ b/src/vulkan/wsi/wsi_common_display.c
@@ -1134,6 +1134,7 @@ static const struct {
} available_surface_formats[] = {
{ .format = VK_FORMAT_B8G8R8A8_SRGB, .drm_format = DRM_FORMAT_XRGB8888 },
{ .format = VK_FORMAT_B8G8R8A8_UNORM, .drm_format = DRM_FORMAT_XRGB8888 },
+ { .format = VK_FORMAT_R5G6B5_UNORM_PACK16, .drm_format = DRM_FORMAT_RGB565 },
};
static void
--
2.17.1

View file

@ -0,0 +1,51 @@
From 505efe31a09ed9ad8291976b95ac77db9397fdcf Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 16 Sep 2021 17:46:28 +0100
Subject: [PATCH 052/168] mesa: partially revert pbuffer attribute removal
This partially reverts commit 5ffd1ebe6b3c8c7dd316dd47fac088044222e6ef
("mesa: Remove misc pbuffer attributes from struct gl_config").
The IMG PowerVR driver sets meaningful values for the maximum
pbuffer width, height and pixels.
---
src/gallium/frontends/dri/dri_util.c | 6 +++---
src/mesa/main/glconfig.h | 5 +++++
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c
index 32ae2b6fec7..ca2655ec536 100644
--- a/src/gallium/frontends/dri/dri_util.c
+++ b/src/gallium/frontends/dri/dri_util.c
@@ -338,9 +338,9 @@ driGetConfigAttribIndex(const __DRIconfig *config,
SIMPLE_CASE(__DRI_ATTRIB_GREEN_MASK, greenMask);
SIMPLE_CASE(__DRI_ATTRIB_BLUE_MASK, blueMask);
SIMPLE_CASE(__DRI_ATTRIB_ALPHA_MASK, alphaMask);
- case __DRI_ATTRIB_MAX_PBUFFER_WIDTH:
- case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT:
- case __DRI_ATTRIB_MAX_PBUFFER_PIXELS:
+ SIMPLE_CASE(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth);
+ SIMPLE_CASE(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight);
+ SIMPLE_CASE(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels);
case __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH:
case __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT:
case __DRI_ATTRIB_VISUAL_SELECT_GROUP:
diff --git a/src/mesa/main/glconfig.h b/src/mesa/main/glconfig.h
index d54a4f75cfd..f9aa5a06940 100644
--- a/src/mesa/main/glconfig.h
+++ b/src/mesa/main/glconfig.h
@@ -27,6 +27,11 @@ struct gl_config
/* ARB_multisample / SGIS_multisample */
GLuint samples;
+ /* GLX 1.3 */
+ GLint maxPbufferWidth;
+ GLint maxPbufferHeight;
+ GLint maxPbufferPixels;
+
/* OML_swap_method */
GLint swapMethod;
--
2.17.1

View file

@ -0,0 +1,66 @@
From 6aed2a165b43231f487a3c0cf2c7835541fe91bf Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 4 Jun 2014 13:43:03 +0100
Subject: [PATCH 053/168] egl_dri2: set pbuffer config attribs to 0 for
non-pbuffer configs
If the EGL_PBUFFER_BIT isn't set in the surface type, don't set the
EGL_MAX_PBUFFER_WIDTH, EGL_MAX_PBUFFER_HEIGHT and
EGL_MAX_PBUFFER_PIXELS attributes to non-zero values when adding an
EGL config. If the EGL_PBUFFER_BIT is set, don't override non-zero
values from the DRI config.
---
src/egl/drivers/dri2/egl_dri2.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 80ba3647a9a..4c52c9aac1a 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -417,6 +417,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
_EGLConfig base;
unsigned int attrib, value, double_buffer;
+ unsigned int pbuffer_width = 0, pbuffer_height = 0, pbuffer_pixels = 0;
bool srgb = false;
EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
int dri_shifts[4] = { -1, -1, -1, -1 };
@@ -540,11 +541,17 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
break;
case __DRI_ATTRIB_MAX_PBUFFER_WIDTH:
- base.MaxPbufferWidth = _EGL_MAX_PBUFFER_WIDTH;
+ pbuffer_width = (value != 0) ? value : _EGL_MAX_PBUFFER_WIDTH;
break;
+
case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT:
- base.MaxPbufferHeight = _EGL_MAX_PBUFFER_HEIGHT;
+ pbuffer_height = (value != 0) ? value : _EGL_MAX_PBUFFER_HEIGHT;
+ break;
+
+ case __DRI_ATTRIB_MAX_PBUFFER_PIXELS:
+ pbuffer_pixels = value;
break;
+
case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER:
if (disp->Extensions.KHR_mutable_render_buffer)
surface_type |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
@@ -624,6 +631,15 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
}
}
+ if (surface_type & EGL_PBUFFER_BIT) {
+ if (pbuffer_pixels == 0)
+ pbuffer_pixels = pbuffer_width * pbuffer_height;
+
+ base.MaxPbufferWidth = pbuffer_width;
+ base.MaxPbufferHeight = pbuffer_height;
+ base.MaxPbufferPixels = pbuffer_pixels;
+ }
+
if (attr_list)
for (int i = 0; attr_list[i] != EGL_NONE; i += 2)
_eglSetConfigKey(&base, attr_list[i], attr_list[i+1]);
--
2.17.1

View file

@ -0,0 +1,146 @@
From 16f7e804e0f4625c17b86fe5247df7257bac7370 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 11 Nov 2021 12:09:38 +0000
Subject: [PATCH 054/168] GL_ARB_geometry_shader4 entry points.
---
src/mapi/glapi/gen/ARB_geometry_shader4.xml | 97 +++++++++++++++++++++
src/mapi/glapi/gen/gl_API.xml | 2 +-
src/mapi/glapi/gen/static_data.py | 4 +
3 files changed, 102 insertions(+), 1 deletion(-)
create mode 100644 src/mapi/glapi/gen/ARB_geometry_shader4.xml
diff --git a/src/mapi/glapi/gen/ARB_geometry_shader4.xml b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
new file mode 100644
index 00000000000..d92dc577b17
--- /dev/null
+++ b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+
+<OpenGLAPI>
+<category name="GL_ARB_geometry_shader4" number="47">
+ <enum name="GEOMETRY_SHADER_ARB" value="0x8DD9"/>
+ <enum name="GEOMETRY_VERTICES_OUT_ARB" value="0x8DDA"/>
+ <enum name="GEOMETRY_INPUT_TYPE_ARB" value="0x8DDB"/>
+ <enum name="GEOMETRY_OUTPUT_TYPE_ARB" value="0x8DDC"/>
+
+ <enum name="MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB"
+ count="1" value="0x8C29">
+ <size name="Get" mode="get"/>
+ </enum>
+ <enum name="MAX_GEOMETRY_VARYING_COMPONENTS_ARB"
+ count="1" value="0x8DDD">
+ <size name="Get" mode="get"/>
+ </enum>
+ <enum name="MAX_VERTEX_VARYING_COMPONENTS_ARB"
+ count="1" value="0x8DDE">
+ <size name="Get" mode="get"/>
+ </enum>
+ <enum name="MAX_VARYING_COMPONENTS"
+ count="1" value="0x8B4B">
+ <size name="Get" mode="get"/>
+ </enum>
+ <enum name="MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB"
+ count="1" value="0x8DDF">
+ <size name="Get" mode="get"/>
+ </enum>
+ <enum name="MAX_GEOMETRY_OUTPUT_VERTICES_ARB"
+ count="1" value="0x8DE0">
+ <size name="Get" mode="get"/>
+ </enum>
+ <enum name="MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB"
+ count="1" value="0x8DE1">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <enum name="LINES_ADJACENCY_ARB" value="0xA"/>
+ <enum name="LINE_STRIP_ADJACENCY_ARB" value="0xB"/>
+ <enum name="TRIANGLES_ADJACENCY_ARB" value="0xC"/>
+ <enum name="TRIANGLE_STRIP_ADJACENCY_ARB" value="0xD"/>
+
+ <enum name="FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB" value="0x8DA8"/>
+ <enum name="FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB" value="0x8DA9"/>
+
+
+ <enum name="FRAMEBUFFER_ATTACHMENT_LAYERED_ARB"
+ count="1" value="0x8DA7">
+ <size name="GetFramebufferAttachmentParameteriv" mode="get"/>
+ </enum>
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER"
+ count="1" value="0x8CD4">
+ <size name="GetFramebufferAttachmentParameteriv" mode="get"/>
+ </enum>
+
+ <enum name="PROGRAM_POINT_SIZE_ARB" value="0x8642"/>
+ <enum name="PROGRAM_POINT_SIZE_ARB"
+ count="1" value="0x8642">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <function name="ProgramParameteriARB" exec="dynamic">
+ <param name="program" type="GLuint"/>
+ <param name="pname" type="GLenum"/>
+ <param name="value" type="GLint"/>
+ </function>
+
+ <function name="FramebufferTextureARB" exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ </function>
+
+ <function name="FramebufferTextureLayerARB" exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="layer" type="GLint"/>
+ </function>
+
+ <function name="FramebufferTextureFaceARB" exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="face" type="GLenum"/>
+ </function>
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 2526770fe35..0e30eb109ed 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -8068,7 +8068,7 @@
<!-- 46. GL_ARB_framebuffer_sRGB -->
-<!-- 47. GL_ARB_geometry_shader4. There are no intentions to implement this extension -->
+<xi:include href="ARB_geometry_shader4.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<!-- 48. GL_ARB_half_float_vertex -->
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index c81845d7f0c..c906125ba75 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1732,6 +1732,10 @@ offsets = {
"FramebufferRenderbufferEXT" : 1696,
"GetFramebufferAttachmentParameterivEXT" : 1697,
"GenerateMipmapEXT" : 1698,
+ "ProgramParameteriARB" : 1699,
+ "FramebufferTextureARB" : 1700,
+ "FramebufferTextureLayerARB" : 1701,
+ "FramebufferTextureFaceARB" : 1702,
}
functions = [
--
2.17.1

View file

@ -0,0 +1,285 @@
From 84039ed0796602a560fd22cec6313ec81daa4044 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 9 Sep 2021 17:55:13 +0100
Subject: [PATCH 055/168] egl/wayland: add EGL_BUFFER_PRESERVED support
When the next back buffer is obtained, and the swap method is
EGL_BUFFER_PRESERVED, the current buffer contents are preserved with
a blit, unless the DRI driver is using the image loader extension,
and the DRI driver requests the current buffer contents
(__DRI_IMAGE_BUFFER_PREV) as well as the back buffer. This allows the
blit to be avoided for GPUs that can support EGL_BUFFER_PRESERVED
directly.
Querying the age of a back buffer may force a blit, but outside of EGL
conformance testing, this would be an odd thing to do, as the buffer
age can always be assumed to be 1 with EGL_BUFFER_PRESERVED.
Any received dmabuf feedback may also force a blit.
The IMG PVR driver does not support the DRI2 loader extension, which
is why the buffer preserved support for the extension is less optimal,
with the current buffer always being preserved with a blit.
EGL_BUFFER_PRESERVED support has not been added for the Mesa software
rasteriser.
---
include/GL/internal/dri_interface.h | 4 ++
src/egl/drivers/dri2/platform_wayland.c | 94 +++++++++++++++++++++----
2 files changed, 83 insertions(+), 15 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 7d96048688d..f2138437bd5 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -2058,12 +2058,16 @@ enum __DRIimageBufferMask {
* OpenGL ES API and little change to the SurfaceFlinger API.
*/
__DRI_IMAGE_BUFFER_SHARED = (1 << 2),
+#define DRI_IMAGE_HAS_BUFFER_PREV
+ __DRI_IMAGE_BUFFER_PREV = (1 << 31),
+
};
struct __DRIimageList {
uint32_t image_mask;
__DRIimage *back;
__DRIimage *front;
+ __DRIimage *prev;
};
#define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 3a9f43e6069..8124697fc90 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -962,12 +962,22 @@ dri2_wl_swap_interval(_EGLDisplay *disp, _EGLSurface *surf, EGLint interval)
}
static void
-dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf)
+dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf,
+ bool release_non_current,
+ bool release_current)
{
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
+ if (dri2_surf->current == &dri2_surf->color_buffers[i]) {
+ if (!release_current)
+ continue;
+ } else {
+ if (!release_non_current)
+ continue;
+ }
+
if (dri2_surf->color_buffers[i].wl_buffer) {
if (dri2_surf->color_buffers[i].locked) {
dri2_surf->color_buffers[i].wl_release = true;
@@ -992,6 +1002,9 @@ dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf)
if (dri2_dpy->dri2)
dri2_egl_surface_free_local_buffers(dri2_surf);
+
+ if (release_current)
+ dri2_surf->current = NULL;
}
static void
@@ -1114,7 +1127,8 @@ create_dri_image(struct dri2_egl_surface *dri2_surf,
}
static int
-get_back_bo(struct dri2_egl_surface *dri2_surf)
+get_back_bo(struct dri2_egl_surface *dri2_surf, bool allow_preserve,
+ bool preserve_current)
{
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
@@ -1200,6 +1214,28 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
return -1;
}
+ if ((allow_preserve || preserve_current) &&
+ dri2_surf->base.SwapBehavior == EGL_BUFFER_PRESERVED &&
+ dri2_surf->current && dri2_surf->back->age != 1) {
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+
+ if (dri2_ctx) {
+ dri2_dpy->image->blitImage(dri2_ctx->dri_context,
+ dri2_surf->back->dri_image,
+ dri2_surf->current->dri_image,
+ 0, 0, dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ 0, 0, dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ __BLIT_FLAG_FLUSH);
+ dri2_surf->back->age = 1;
+
+ if (!preserve_current)
+ dri2_surf->current = NULL;
+ }
+ }
+
dri2_surf->back->locked = true;
return 0;
@@ -1257,8 +1293,12 @@ front_bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy,
static int
update_buffers(struct dri2_egl_display *dri2_dpy,
- struct dri2_egl_surface *dri2_surf)
+ struct dri2_egl_surface *dri2_surf,
+ bool allow_preserve)
{
+ bool preserve_current = false;
+ int res;
+
if (dri2_surf->wl_win &&
(dri2_surf->base.Width != dri2_surf->wl_win->width ||
dri2_surf->base.Height != dri2_surf->wl_win->height)) {
@@ -1268,12 +1308,20 @@ update_buffers(struct dri2_egl_display *dri2_dpy,
}
if (dri2_surf->resized || dri2_surf->received_dmabuf_feedback) {
- dri2_wl_release_buffers(dri2_surf);
+ preserve_current = !dri2_surf->resized &&
+ dri2_surf->base.SwapBehavior == EGL_BUFFER_PRESERVED;
+
+ dri2_wl_release_buffers(dri2_surf, true, !preserve_current);
dri2_surf->resized = false;
dri2_surf->received_dmabuf_feedback = false;
}
- if (get_back_bo(dri2_surf) < 0) {
+ res = get_back_bo(dri2_surf, allow_preserve, preserve_current);
+
+ if (preserve_current)
+ dri2_wl_release_buffers(dri2_surf, false, true);
+
+ if (res < 0) {
_eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
return -1;
}
@@ -1303,12 +1351,13 @@ update_buffers(struct dri2_egl_display *dri2_dpy,
static int
update_buffers_if_needed(struct dri2_egl_display *dri2_dpy,
- struct dri2_egl_surface *dri2_surf)
+ struct dri2_egl_surface *dri2_surf,
+ bool allow_preserve)
{
if (dri2_surf->back != NULL)
return 0;
- return update_buffers(dri2_dpy, dri2_surf);
+ return update_buffers(dri2_dpy, dri2_surf, allow_preserve);
}
static __DRIbuffer *
@@ -1327,7 +1376,7 @@ dri2_wl_get_buffers_with_format(__DRIdrawable * driDrawable,
switch (attachments[i]) {
case __DRI_BUFFER_BACK_LEFT:
- if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0)
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf, true) < 0)
return NULL;
back_bo_to_dri_buffer(dri2_dpy, dri2_surf, &dri2_surf->buffers[j]);
@@ -1412,14 +1461,25 @@ image_get_buffers(__DRIdrawable *driDrawable,
buffers->image_mask = 0;
buffers->front = NULL;
buffers->back = NULL;
+ buffers->prev = NULL;
if (buffer_mask & __DRI_IMAGE_BUFFER_BACK)
{
- if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0)
+ bool buffer_prev = buffer_mask & __DRI_IMAGE_BUFFER_PREV;
+
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf, !buffer_prev) < 0)
return 0;
buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
buffers->back = dri2_surf->back->dri_image;
+
+ if (buffer_prev && dri2_surf->current &&
+ dri2_surf->base.SwapBehavior == EGL_BUFFER_PRESERVED)
+ {
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_PREV;
+ buffers->prev = dri2_surf->current->dri_image;
+ dri2_surf->back->age = 1;
+ }
}
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT)
@@ -1717,7 +1777,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
/* Make sure we have a back buffer in case we're swapping without ever
* rendering. */
- if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0)
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf, true) < 0)
return _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
if (draw->SwapInterval > 0) {
@@ -1804,7 +1864,7 @@ dri2_wl_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface)
if (surface->Type != EGL_WINDOW_BIT)
return 0;
- if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0) {
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf, true) < 0) {
_eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
return -1;
}
@@ -2186,7 +2246,7 @@ static const __DRIextension *image_loader_extensions[] = {
};
static EGLBoolean
-dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
+dri2_wl_add_configs_for_visuals(_EGLDisplay *disp, bool allow_preserve)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
unsigned int format_count[ARRAY_SIZE(dri2_wl_visuals)] = { 0 };
@@ -2207,6 +2267,10 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
if (dri2_wl_visuals[j].wl_drm_format != WL_DRM_FORMAT_YUYV)
surface_type |= EGL_PBUFFER_BIT;
+ if (allow_preserve &&
+ dri2_dpy->image->base.version >= 9 && dri2_dpy->image->blitImage)
+ surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
count + 1, surface_type, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
if (dri2_conf) {
@@ -2443,7 +2507,7 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
goto cleanup;
}
- if (!dri2_wl_add_configs_for_visuals(disp)) {
+ if (!dri2_wl_add_configs_for_visuals(disp, true)) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to add configs");
goto cleanup;
}
@@ -2555,7 +2619,7 @@ swrast_update_buffers(struct dri2_egl_surface *dri2_surf)
dri2_surf->base.Height != dri2_surf->wl_win->height)) {
if (!zink)
- dri2_wl_release_buffers(dri2_surf);
+ dri2_wl_release_buffers(dri2_surf, true, true);
dri2_surf->base.Width = dri2_surf->wl_win->width;
dri2_surf->base.Height = dri2_surf->wl_win->height;
@@ -3002,7 +3066,7 @@ dri2_initialize_wayland_swrast(_EGLDisplay *disp)
dri2_wl_setup_swap_interval(disp);
- if (!dri2_wl_add_configs_for_visuals(disp)) {
+ if (!dri2_wl_add_configs_for_visuals(disp, false)) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to add configs");
goto cleanup;
}
--
2.17.1

View file

@ -0,0 +1,28 @@
From 462716a04a43d23ff35aa0eb147f58fa336eff1c Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Wed, 23 Mar 2022 12:57:01 +0000
Subject: [PATCH 056/168] glapi: restore exec="dynamic"
This is needed for the dispatch table entry points used by the IMG
Rogue DDK driver, which have no implementation in Mesa. Using
exec="dynamic" avoids the need to create stubs in Mesa for the
unimplemented functions.
---
src/mapi/glapi/gen/api_exec_init.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/mapi/glapi/gen/api_exec_init.py b/src/mapi/glapi/gen/api_exec_init.py
index 3f862287768..28b2395ce47 100644
--- a/src/mapi/glapi/gen/api_exec_init.py
+++ b/src/mapi/glapi/gen/api_exec_init.py
@@ -34,6 +34,7 @@ import apiexec
exec_flavor_map = {
'beginend': None,
+ 'dynamic': None,
'dlist': '_mesa_',
'mesa': '_mesa_',
'skip': None,
--
2.17.1

View file

@ -0,0 +1,42 @@
From 00f9320539178cacf9dd75104f61f07a303b9960 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Fri, 29 Apr 2022 14:48:06 +0100
Subject: [PATCH 057/168] Revert "meson: check -mtls if has_exe_wrapper"
This reverts commit 558bc2227ed00fc6a29c2a10c0b99719cd445c6c.
The change breaks 32 bit x86 cross compilation on x86_64 systems, as
meson.has_exe_wrapper returns true, but Meson fails with:
Build machine cpu family: x86_64
Build machine cpu: x86_64
Host machine cpu family: x86
Host machine cpu: i686
Target machine cpu family: x86
Target machine cpu: i686
Checking if "thread_local" compiles: YES
meson.build:555:4: ERROR: Can not run test applications in this
cross environment.
See also https://github.com/mesonbuild/meson/issues/9845
---
meson.build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index ee142c5b4b5..53019fc2e3f 100644
--- a/meson.build
+++ b/meson.build
@@ -566,7 +566,7 @@ endforeach
if not have_mtls_dialect
# need .run to check libc support. meson aborts when calling .run when
# cross-compiling, but because this is just an optimization we can skip it
- if meson.is_cross_build() and not meson.has_exe_wrapper()
+ if meson.is_cross_build()
warning('cannot auto-detect -mtls-dialect when cross-compiling, using compiler default')
else
# -fpic to force dynamic tls, otherwise TLS relaxation defeats check
--
2.17.1

View file

@ -0,0 +1,271 @@
From b5785681453f05818e2c077a2304427774c82b11 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 24 Jan 2023 21:41:48 +0000
Subject: [PATCH 058/168] vulkan/wsi: extend PVR WSI library to destroy
surfaces
Up until now, the Rogue DDK has destroyed surfaces without using the
library, by simply freeing the surface. Changes to surface allocation
for Wayland mean that this is no longer possible, as additional
cleanup is required.
---
src/pvr/wsi/pvr_mesa_wsi_interface.h | 24 ++++++++++++++++++++
src/pvr/wsi/pvr_wsi.c | 34 ++++++++++++++++++++++++++++
src/pvr/wsi/pvr_wsi.h | 5 +++-
src/vulkan/wsi/wsi_common.c | 28 +++++++++++++++++------
src/vulkan/wsi/wsi_common.h | 4 ++++
src/vulkan/wsi/wsi_common_private.h | 2 +-
src/vulkan/wsi/wsi_common_wayland.c | 5 ++--
7 files changed, 90 insertions(+), 12 deletions(-)
diff --git a/src/pvr/wsi/pvr_mesa_wsi_interface.h b/src/pvr/wsi/pvr_mesa_wsi_interface.h
index b4b1bcb0c9d..46430b56c63 100644
--- a/src/pvr/wsi/pvr_mesa_wsi_interface.h
+++ b/src/pvr/wsi/pvr_mesa_wsi_interface.h
@@ -42,6 +42,8 @@ struct pvr_mesa_wsi;
/*
* Functions defined in Mesa for use by the PowerVR DDK.
* All functions have a "pvr_mesa_wsi" prefix.
+ * Since the introduction of version 1 of the interface, the following
+ * functions are now regarded as forming version 0 of the interface.
*/
void *
@@ -295,12 +297,34 @@ pvr_mesa_wsi_get_swapchain_counter(struct pvr_mesa_wsi *mwsi,
VkSurfaceCounterFlagBitsEXT flagBits,
uint64_t *pValue);
+/*
+ * The following are available in version 1 of the interface.
+ * Version 1 also supports the version 0 interface.
+ */
+
+uint32_t
+pvr_mesa_wsi_get_version(struct pvr_mesa_wsi *mwsi);
+
+void
+pvr_mesa_wsi_surface_destroy(struct pvr_mesa_wsi *mwsi,
+ VkSurfaceKHR surface,
+ const VkAllocationCallbacks *pAllocator);
+
/*
* Functions defined in the PowerVR DDK for use by Mesa.
* All functions have a "pvr_vk_mesa_wsi" prefix.
+ * Since the introduction of version 1 of the interface, the following
+ * function is now regarded as forming version 0 of the interface.
*/
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
pvr_vk_mesa_wsi_sym_addr(VkPhysicalDevice physicalDevice,
const char *name);
+/*
+ * The following is available in version 1 of the interface.
+ * Version 1 also supports the version 0 interface.
+ */
+uint32_t
+pvr_vk_mesa_wsi_get_version(VkPhysicalDevice physicalDevice);
+
#endif /* PVR_MESA_WSI_INTERFACE_H */
diff --git a/src/pvr/wsi/pvr_wsi.c b/src/pvr/wsi/pvr_wsi.c
index f1e4bc594c8..cbf2b7a086f 100644
--- a/src/pvr/wsi/pvr_wsi.c
+++ b/src/pvr/wsi/pvr_wsi.c
@@ -27,6 +27,16 @@
#include "pvr_wsi.h"
#include "pvr_mesa_wsi_interface.h"
+static inline uint32_t
+pvr_vk_wsi_get_version(struct pvr_mesa_wsi *mwsi)
+{
+ JUMP_DDK(mwsi, pvr_vk_mesa_wsi_get_version,
+ mwsi->physicalDevice);
+
+ return 0;
+}
+
+
VkResult
pvr_mesa_wsi_init(struct pvr_mesa_wsi **pmwsi,
VkPhysicalDevice physicalDevice,
@@ -47,6 +57,12 @@ pvr_mesa_wsi_init(struct pvr_mesa_wsi **pmwsi,
mwsi->symtab.pvr_vk_mesa_wsi_sym_addr = pvr_vk_mesa_wsi_sym_addr;
mwsi->physicalDevice = physicalDevice;
+ mwsi->pvr_vk_wsi_version = pvr_vk_wsi_get_version(mwsi);
+ if (mwsi->pvr_vk_wsi_version < 1) {
+ vk_free(alloc, mwsi);
+ return VK_ERROR_FEATURE_NOT_PRESENT;
+ }
+
result = wsi_device_init2(&mwsi->wsi,
physicalDevice,
pvr_vk_mesa_wsi_sym_addr,
@@ -227,6 +243,20 @@ pvr_mesa_wsi_common_get_present_rectangles(struct pvr_mesa_wsi *mwsi,
pRects);
}
+uint32_t
+pvr_mesa_wsi_get_version(UNUSED struct pvr_mesa_wsi *mwsi)
+{
+ return 1;
+}
+
+void
+pvr_mesa_wsi_surface_destroy(UNUSED struct pvr_mesa_wsi *mwsi,
+ VkSurfaceKHR surface,
+ const VkAllocationCallbacks *pAllocator)
+{
+ wsi_surface_destroy(surface, pAllocator);
+}
+
/*
* The mwsi parameter is currently unused. Note that it is invalid for
* pvr_mesa_wsi_init, which is responsible for allocating it.
@@ -322,6 +352,10 @@ pvr_mesa_wsi_sym_addr(UNUSED struct pvr_mesa_wsi *mwsi, const char *name)
pvr_mesa_wsi_register_display_event },
{ "pvr_mesa_wsi_get_swapchain_counter",
pvr_mesa_wsi_get_swapchain_counter },
+ { "pvr_mesa_wsi_get_version",
+ pvr_mesa_wsi_get_version },
+ { "pvr_mesa_wsi_surface_destroy",
+ pvr_mesa_wsi_surface_destroy },
};
unsigned i;
diff --git a/src/pvr/wsi/pvr_wsi.h b/src/pvr/wsi/pvr_wsi.h
index 142358db3de..0c734fdb1f5 100644
--- a/src/pvr/wsi/pvr_wsi.h
+++ b/src/pvr/wsi/pvr_wsi.h
@@ -37,7 +37,7 @@
#define MAKE_STRING(x) _MAKE_STRING(x)
#define LOOKUP_DDK(mwsi, sym) \
- mwsi->symtab.pvr_vk_mesa_wsi_sym_addr(MAKE_STRING(sym))
+ mwsi->symtab.pvr_vk_mesa_wsi_sym_addr(mwsi->physicalDevice, MAKE_STRING(sym))
#define JUMP_DDK(mwsi, sym, ...) \
do { \
@@ -61,6 +61,8 @@ struct pvr_vk_mesa_wsi_sym_tab
{
PFN_vkVoidFunction (VKAPI_PTR *pvr_vk_mesa_wsi_sym_addr)
(VkPhysicalDevice physicalDevice, const char *);
+
+ uint32_t (*pvr_vk_mesa_wsi_get_version)(VkPhysicalDevice physicalDevice);
};
struct pvr_mesa_wsi
@@ -68,6 +70,7 @@ struct pvr_mesa_wsi
struct wsi_device wsi;
struct pvr_vk_mesa_wsi_sym_tab symtab;
VkPhysicalDevice physicalDevice;
+ uint32_t pvr_vk_wsi_version;
};
static inline struct pvr_mesa_wsi *pvr_mesa_wsi(struct wsi_device *wsi_ptr)
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
index 389117ceb2e..8067781c459 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
@@ -291,12 +291,10 @@ wsi_device_finish(struct wsi_device *wsi,
#endif
}
-VKAPI_ATTR void VKAPI_CALL
-wsi_DestroySurfaceKHR(VkInstance _instance,
- VkSurfaceKHR _surface,
- const VkAllocationCallbacks *pAllocator)
+void
+wsi_surface_destroy(VkSurfaceKHR _surface,
+ const VkAllocationCallbacks *pAllocator)
{
- VK_FROM_HANDLE(vk_instance, instance, _instance);
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
if (!surface)
@@ -304,12 +302,28 @@ wsi_DestroySurfaceKHR(VkInstance _instance,
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
if (surface->platform == VK_ICD_WSI_PLATFORM_WAYLAND) {
- wsi_wl_surface_destroy(surface, _instance, pAllocator);
+ wsi_wl_surface_destroy(surface, pAllocator);
return;
}
#endif
- vk_free2(&instance->alloc, pAllocator, surface);
+ vk_free(pAllocator, surface);
+}
+
+VKAPI_ATTR void VKAPI_CALL
+wsi_DestroySurfaceKHR(VkInstance _instance,
+ VkSurfaceKHR _surface,
+ const VkAllocationCallbacks *pAllocator)
+{
+ VK_FROM_HANDLE(vk_instance, instance, _instance);
+ const VkAllocationCallbacks *allocator;
+
+ if (pAllocator)
+ allocator = pAllocator;
+ else
+ allocator = &instance->alloc;
+
+ wsi_surface_destroy(_surface, allocator);
}
void
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index aec1021113e..3a47be66859 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -393,6 +393,10 @@ wsi_common_bind_swapchain_image(const struct wsi_device *wsi,
VkSwapchainKHR _swapchain,
uint32_t image_idx);
+void
+wsi_surface_destroy(VkSurfaceKHR _surface,
+ const VkAllocationCallbacks *pAllocator);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h
index 868fdf968e4..631ea93e3d6 100644
--- a/src/vulkan/wsi/wsi_common_private.h
+++ b/src/vulkan/wsi/wsi_common_private.h
@@ -171,7 +171,7 @@ bool
wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd);
void
-wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance,
+wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface,
const VkAllocationCallbacks *pAllocator);
VkResult
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index bffc52da13f..da3575fc584 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -1273,10 +1273,9 @@ wsi_wl_surface_get_present_rectangles(VkIcdSurfaceBase *surface,
}
void
-wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance,
+wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface,
const VkAllocationCallbacks *pAllocator)
{
- VK_FROM_HANDLE(vk_instance, instance, _instance);
struct wsi_wl_surface *wsi_wl_surface =
wl_container_of((VkIcdSurfaceWayland *)icd_surface, wsi_wl_surface, base);
@@ -1292,7 +1291,7 @@ wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance,
dmabuf_feedback_fini(&wsi_wl_surface->pending_dmabuf_feedback);
}
- vk_free2(&instance->alloc, pAllocator, wsi_wl_surface);
+ vk_free(pAllocator, wsi_wl_surface);
}
static struct wsi_wl_format *
--
2.17.1

View file

@ -0,0 +1,45 @@
From 8cbccbc6182f92a6256ef73bfb1a74eec0ccc5f6 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Tue, 17 Jan 2023 19:24:13 +0000
Subject: [PATCH 059/168] vulkan/wsi: dEQP
wayland.swapchain.simulate_oom.min_image_count fix
Fix for segfault with dEQP test case
dEQP-VK.wsi.wayland.swapchain.simulate_oom.min_image_count.
In wsi_wl_surface_create_swapchain, if wsi_wl_surface_init failed,
wsi_wl_swapchain_chain_free was called without wsi_swapchain_init
having been called, resulting in a segfault in wsi_swapchain_finish,
due to chain->wsi having never been initialised.
---
src/vulkan/wsi/wsi_common_wayland.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index da3575fc584..e292ec4c70f 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -1940,8 +1940,10 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
wsi_wl_surface->chain = chain;
result = wsi_wl_surface_init(wsi_wl_surface, wsi_device);
- if (result != VK_SUCCESS)
- goto fail;
+ if (result != VK_SUCCESS) {
+ vk_free(pAllocator, chain);
+ return result;
+ }
enum wsi_wl_buffer_type buffer_type;
struct wsi_base_image_params *image_params = NULL;
@@ -2039,7 +2041,6 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
fail_image_init:
wsi_wl_swapchain_images_free(chain);
-fail:
wsi_wl_swapchain_chain_free(chain, pAllocator);
return result;
--
2.17.1

View file

@ -0,0 +1,64 @@
From 1bc869491d51631c3fe0c6b2f2373e7b0c4fca84 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Thu, 26 Jan 2023 16:23:27 +0000
Subject: [PATCH 060/168] vulkan/wsi/wayland: allocate memory for swapchain
modifier array
A pointer to the array of DRM format modifiers is stored in the
swapchain. If the pointer is derived from dmabuf feedback, it may
become invalid when new feedback is received, making the comparison
done by surface_dmabuf_feedback_tranche_done unreliable.
---
src/vulkan/wsi/wsi_common_wayland.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index e292ec4c70f..bf242e19c16 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -1884,6 +1884,8 @@ wsi_wl_swapchain_chain_free(struct wsi_wl_swapchain *chain,
wsi_swapchain_finish(&chain->base);
+ vk_free(pAllocator, (void *)chain->drm_modifiers);
+
vk_free(pAllocator, chain);
}
@@ -2022,8 +2024,24 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
} else {
chain->shm_format = wl_shm_format_for_vk_format(chain->vk_format, alpha);
}
+
chain->num_drm_modifiers = num_drm_modifiers;
- chain->drm_modifiers = drm_modifiers;
+ if (num_drm_modifiers > 0) {
+ uint64_t *modifiers;
+
+ modifiers = vk_alloc(pAllocator, sizeof(*modifiers) * num_drm_modifiers,
+ 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!modifiers) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto fail_modifiers_alloc;
+ }
+
+ for (uint32_t i = 0; i < num_drm_modifiers; i++)
+ modifiers[i] = drm_modifiers[i];
+
+ chain->drm_modifiers = modifiers;
+ }
+
chain->fifo_ready = true;
for (uint32_t i = 0; i < chain->base.image_count; i++) {
@@ -2041,6 +2059,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
fail_image_init:
wsi_wl_swapchain_images_free(chain);
+fail_modifiers_alloc:
wsi_wl_swapchain_chain_free(chain, pAllocator);
return result;
--
2.17.1

View file

@ -0,0 +1,108 @@
From 9c388aa5a84373b65859ed680b785c1cc50249a9 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Fri, 11 Nov 2022 10:35:40 +0100
Subject: [PATCH 061/168] zink: remove descriptor-mode selection infrastructure
We only support lazy descriptors these days, so having the
infrastructure around to support automatic selection of that one mode is
kinda silly.
And it's not like setting an environment variable that is never read is
going to cause any issues, so we don't even need this to avoid breaking
existing setups.
Let's just rip it out. We can reintroduce it again on the off-chance
that someone has a new clever descriptor mode they want to experiment
with.
Reviewed-by: Hoe Hao Cheng <haochengho12907@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19670>
---
docs/drivers/zink.rst | 13 -------------
src/gallium/drivers/zink/zink_screen.c | 15 ---------------
src/gallium/drivers/zink/zink_types.h | 5 -----
3 files changed, 33 deletions(-)
diff --git a/docs/drivers/zink.rst b/docs/drivers/zink.rst
index 157ecc82e4a..7bf397796f6 100644
--- a/docs/drivers/zink.rst
+++ b/docs/drivers/zink.rst
@@ -247,19 +247,6 @@ are required to be supported
* `VK_KHR_draw_indirect_count`_
-Performance
------------
-
-If you notice poor performance and high CPU usage while running an application,
-changing the descriptor manager may improve performance:
-
-.. envvar:: ZINK_DESCRIPTORS <mode> ("auto")
-
-``auto``
- Automatically detect best mode. This is the default.
-``lazy``
- Attempt to use the least amount of CPU by binding descriptors opportunistically.
-
Debugging
---------
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index 3427b68cd8c..79d85ce1899 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -89,17 +89,6 @@ uint32_t
zink_debug;
-static const struct debug_named_value
-zink_descriptor_options[] = {
- { "auto", ZINK_DESCRIPTOR_MODE_AUTO, "Automatically detect best mode" },
- { "lazy", ZINK_DESCRIPTOR_MODE_LAZY, "Don't cache, do least amount of updates" },
- DEBUG_NAMED_VALUE_END
-};
-
-DEBUG_GET_ONCE_FLAGS_OPTION(zink_descriptor_mode, "ZINK_DESCRIPTORS", zink_descriptor_options, ZINK_DESCRIPTOR_MODE_AUTO)
-
-enum zink_descriptor_mode zink_descriptor_mode;
-
static const char *
zink_get_vendor(struct pipe_screen *pscreen)
{
@@ -2451,7 +2440,6 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
screen->abort_on_hang = debug_get_bool_option("ZINK_HANG_ABORT", false);
zink_debug = debug_get_option_zink_debug();
- zink_descriptor_mode = debug_get_option_zink_descriptor_mode();
screen->loader_lib = util_dl_open(VK_LIBNAME);
if (!screen->loader_lib)
@@ -2560,9 +2548,6 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_IMAGE] = 4;
screen->desc_set_id[ZINK_DESCRIPTOR_BINDLESS] = 5;
}
- if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_AUTO) {
- zink_descriptor_mode = ZINK_DESCRIPTOR_MODE_LAZY;
- }
if (screen->info.have_EXT_calibrated_timestamps && !check_have_device_time(screen))
goto fail;
diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h
index b05ad12ed18..7968e44aad2 100644
--- a/src/gallium/drivers/zink/zink_types.h
+++ b/src/gallium/drivers/zink/zink_types.h
@@ -147,11 +147,6 @@ enum zink_descriptor_type {
ZINK_DESCRIPTOR_NON_BINDLESS_TYPES = ZINK_DESCRIPTOR_BASE_TYPES + 1, /**< for struct sizing */
};
-enum zink_descriptor_mode {
- ZINK_DESCRIPTOR_MODE_AUTO,
- ZINK_DESCRIPTOR_MODE_LAZY,
-};
-
/* indexing for descriptor template management */
enum zink_descriptor_size_index {
ZDS_INDEX_UBO,
--
2.17.1

View file

@ -0,0 +1,37 @@
From fdad4f15f39f0f202c956dae599397e7c0b20e43 Mon Sep 17 00:00:00 2001
From: Imagination Technologies <powervr@imgtec.com>
Date: Mon, 21 Nov 2022 13:53:04 +0100
Subject: [PATCH 062/168] aux/draw: vectorize aaline computations
This makes it a bit more similar to the TGSI version, which makes
modifying them easier to review.
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19899>
---
src/gallium/auxiliary/nir/nir_draw_helpers.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.c b/src/gallium/auxiliary/nir/nir_draw_helpers.c
index daa1fcb260b..098b83b194b 100644
--- a/src/gallium/auxiliary/nir/nir_draw_helpers.c
+++ b/src/gallium/auxiliary/nir/nir_draw_helpers.c
@@ -174,12 +174,10 @@ nir_lower_aaline_block(nir_block *block,
nir_ssa_def *out_input = intrin->src[1].ssa;
b->cursor = nir_before_instr(instr);
nir_ssa_def *lw = nir_load_var(b, state->line_width_input);
- nir_ssa_def *tmp = nir_fsat(b, nir_fadd(b, nir_channel(b, lw, 1),
- nir_fneg(b, nir_fabs(b, nir_channel(b, lw, 0)))));
- nir_ssa_def *tmp1 = nir_fsat(b, nir_fadd(b, nir_channel(b, lw, 3),
- nir_fneg(b, nir_fabs(b, nir_channel(b, lw, 2)))));
+ nir_ssa_def *tmp = nir_fsat(b, nir_fadd(b, nir_channels(b, lw, 0xa),
+ nir_fneg(b, nir_fabs(b, nir_channels(b, lw, 0x5)))));
- tmp = nir_fmul(b, tmp, tmp1);
+ tmp = nir_fmul(b, nir_channel(b, tmp, 0), nir_channel(b, tmp, 1));
tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp);
nir_ssa_def *out = nir_vec4(b, nir_channel(b, out_input, 0),
--
2.17.1

Some files were not shown because too many files have changed in this diff Show more