c68df0fa59977c54da91184153d268a7bcb04884 — Drew DeVault 2 months ago 60d89ef master
Fix EGL surface creation on AMDGPU

We have to search for a suitable config, rather than assuming that the
first is correct.
2 files changed, 48 insertions(+), 7 deletions(-)

M common.c
M common.h
M common.c => common.c +47 -7
@@ 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 @@   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 @@ 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 @@ 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;
  	}
  

M common.h => common.h +1 -0
@@ 57,6 57,7 @@ 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);