[Mesa-dev] [PATCH kmscube v2] Fix EGL surface creation on AMDGPU

Drew DeVault sir at cmpwn.com
Thu Jul 4 15:19:30 UTC 2019


We have to search for a suitable config, rather than assuming that the
first is correct.
---
I was originally just throwing shit from the wlroots EGL setup code at
this to see if I could fix the problem, which is why there were some
unrelated changes in v1. Thanks to Daniel and Emil for helping me narrow
it down to just the relevant changes.

 common.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++-------
 common.h |  1 +
 2 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/common.c b/common.c
index f9bd280..0922fba 100644
--- a/common.c
+++ b/common.c
@@ -21,23 +21,62 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "common.h"
 
+static bool egl_get_config(EGLDisplay disp, const EGLint *attribs,
+		EGLConfig *out, EGLint visual_id)
+{
+	EGLint count = 0, matched = 0, ret;
+
+	ret = eglGetConfigs(disp, NULL, 0, &count);
+	if (ret == EGL_FALSE || count == 0) {
+		printf("eglGetConfigs returned no configs\n");
+		return false;
+	}
+
+	EGLConfig configs[128];
+	assert((size_t)count < sizeof(configs) / sizeof(configs[0]));
+
+	ret = eglChooseConfig(disp, attribs, configs, count, &matched);
+	if (ret == EGL_FALSE) {
+		printf("eglChooseConfig failed\n");
+		return false;
+	}
+
+	for (int i = 0; i < matched; ++i) {
+		EGLint visual;
+		if (!eglGetConfigAttrib(disp, configs[i],
+				EGL_NATIVE_VISUAL_ID, &visual)) {
+			continue;
+		}
+
+		if (!visual_id || visual == visual_id) {
+			*out = configs[i];
+			return true;
+		}
+	}
+
+	printf("no valid egl config found\n");
+	return false;
+}
+
 struct gbm * init_gbm(int drm_fd, int w, int h)
 {
-        struct gbm *gbm = calloc(1, sizeof (struct gbm));
+	struct gbm *gbm = calloc(1, sizeof (struct gbm));
 
 	gbm->dev = gbm_create_device(drm_fd);
 
+	gbm->format = GBM_FORMAT_XRGB8888;
 	gbm->surface = gbm_surface_create(gbm->dev, w, h,
-			GBM_FORMAT_XRGB8888,
-			GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+			gbm->format, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
 	if (!gbm->surface) {
 		printf("failed to create gbm surface\n");
 		return NULL;
@@ -52,7 +91,7 @@ struct gbm * init_gbm(int drm_fd, int w, int h)
 
 int init_egl(struct egl *egl, const struct gbm *gbm)
 {
-	EGLint major, minor, n;
+	EGLint major, minor;
 
 	static const EGLint context_attribs[] = {
 		EGL_CONTEXT_CLIENT_VERSION, 2,
@@ -106,8 +145,9 @@ int init_egl(struct egl *egl, const struct gbm *gbm)
 		return -1;
 	}
 
-	if (!eglChooseConfig(egl->display, config_attribs, &egl->config, 1, &n) || n != 1) {
-		printf("failed to choose config: %d\n", n);
+	if (!egl_get_config(egl->display, config_attribs,
+				&egl->config, gbm->format)) {
+		printf("Failed to get EGL config\n");
 		return -1;
 	}
 
@@ -121,7 +161,7 @@ int init_egl(struct egl *egl, const struct gbm *gbm)
 	egl->surface = eglCreateWindowSurface(egl->display, egl->config,
 			(EGLNativeWindowType)gbm->surface, NULL);
 	if (egl->surface == EGL_NO_SURFACE) {
-		printf("failed to create egl surface\n");
+		printf("failed to create egl surface: %d\n", eglGetError());
 		return -1;
 	}
 
diff --git a/common.h b/common.h
index 1ddf04b..785b4e8 100644
--- a/common.h
+++ b/common.h
@@ -57,6 +57,7 @@ struct gbm {
 	struct gbm_device *dev;
 	struct gbm_surface *surface;
 	int width, height;
+	uint32_t format;
 };
 
 struct gbm * init_gbm(int drm_fd, int w, int h);
-- 
2.22.0



More information about the mesa-dev mailing list