[kmscube,v2] Fix EGL surface creation on AMDGPU

Submitted by Drew DeVault on July 4, 2019, 3:19 p.m.

Details

Message ID 20190704151930.26619-1-sir@cmpwn.com
State New
Headers show
Series "Fix EGL surface creation on AMDGPU" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Drew DeVault July 4, 2019, 3:19 p.m.
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(-)

Patch hide | download patch | download mbox

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);