dril: rework config creation
the original implementation of config selection had a number of flaws:
* using eglChooseConfigs with lots of loops, which was okay for filtering but
also added considerable complexity and made it difficult to correctly
get all the configs
* not adding enough configs; there were a lot more color and zs formats
which weren't in the base config list
* double buffer configs were never created
* srgb configs were also never created
there will now be fewer configs than there were pre-DRIL, but this is only
because accum buffers are now gone and not because anything of value is
missing
Fixes: 3de62b2f9a
("gallium/dril: Compatibility stub for the legacy DRI loader interface")
Acked-by: Daniel Stone <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30311>
This commit is contained in:

committed by
Marge Bot

parent
dd5362c78a
commit
ec7afd2c24
@@ -26,6 +26,7 @@
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include "gbm/main/gbm.h"
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
|
||||
#define EGL_PLATFORM_GBM_MESA 0x31D7
|
||||
|
||||
@@ -33,33 +34,38 @@
|
||||
#define GLX_NONE 0x8000
|
||||
#define GLX_DONT_CARE 0xFFFFFFFF
|
||||
|
||||
#define CONFIG_DB(color, zs, doublebuffer) \
|
||||
#define CONFIG_ZS(color, zs) \
|
||||
{ \
|
||||
.color_format = color, \
|
||||
.zs_format = zs, \
|
||||
.doubleBufferMode = doublebuffer, \
|
||||
}
|
||||
#define CONFIG(color, zs) \
|
||||
CONFIG_DB(color, zs, GL_TRUE), \
|
||||
CONFIG_DB(color, zs, GL_FALSE)
|
||||
|
||||
#define CONFIG(color) \
|
||||
CONFIG_ZS(color, PIPE_FORMAT_S8_UINT), \
|
||||
CONFIG_ZS(color, PIPE_FORMAT_Z24_UNORM_S8_UINT), \
|
||||
CONFIG_ZS(color, PIPE_FORMAT_Z24X8_UNORM), \
|
||||
CONFIG_ZS(color, PIPE_FORMAT_Z16_UNORM), \
|
||||
CONFIG_ZS(color, PIPE_FORMAT_NONE) \
|
||||
|
||||
static const struct gl_config drilConfigs[] = {
|
||||
CONFIG(PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_S8_UINT),
|
||||
CONFIG(PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_Z24_UNORM_S8_UINT),
|
||||
CONFIG(PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_NONE),
|
||||
CONFIG(PIPE_FORMAT_R8G8B8X8_UNORM, PIPE_FORMAT_S8_UINT),
|
||||
CONFIG(PIPE_FORMAT_R8G8B8X8_UNORM, PIPE_FORMAT_Z24_UNORM_S8_UINT),
|
||||
CONFIG(PIPE_FORMAT_R8G8B8X8_UNORM, PIPE_FORMAT_NONE),
|
||||
CONFIG(PIPE_FORMAT_R10G10B10A2_UNORM, PIPE_FORMAT_S8_UINT),
|
||||
CONFIG(PIPE_FORMAT_R10G10B10A2_UNORM, PIPE_FORMAT_Z24_UNORM_S8_UINT),
|
||||
CONFIG(PIPE_FORMAT_R10G10B10A2_UNORM, PIPE_FORMAT_NONE),
|
||||
CONFIG(PIPE_FORMAT_R10G10B10X2_UNORM, PIPE_FORMAT_S8_UINT),
|
||||
CONFIG(PIPE_FORMAT_R10G10B10X2_UNORM, PIPE_FORMAT_Z24_UNORM_S8_UINT),
|
||||
CONFIG(PIPE_FORMAT_R10G10B10X2_UNORM, PIPE_FORMAT_NONE),
|
||||
CONFIG(PIPE_FORMAT_R5G6B5_UNORM, PIPE_FORMAT_S8_UINT),
|
||||
CONFIG(PIPE_FORMAT_R5G6B5_UNORM, PIPE_FORMAT_Z16_UNORM),
|
||||
CONFIG(PIPE_FORMAT_R5G6B5_UNORM, PIPE_FORMAT_NONE),
|
||||
// etc...
|
||||
CONFIG(PIPE_FORMAT_R8G8B8A8_UNORM),
|
||||
CONFIG(PIPE_FORMAT_R8G8B8X8_UNORM),
|
||||
CONFIG(PIPE_FORMAT_B8G8R8A8_UNORM),
|
||||
CONFIG(PIPE_FORMAT_B8G8R8X8_UNORM),
|
||||
CONFIG(PIPE_FORMAT_R10G10B10A2_UNORM),
|
||||
CONFIG(PIPE_FORMAT_R10G10B10X2_UNORM),
|
||||
CONFIG(PIPE_FORMAT_B10G10R10A2_UNORM),
|
||||
CONFIG(PIPE_FORMAT_B10G10R10X2_UNORM),
|
||||
CONFIG(PIPE_FORMAT_R5G6B5_UNORM),
|
||||
CONFIG(PIPE_FORMAT_R5G5B5A1_UNORM),
|
||||
CONFIG(PIPE_FORMAT_R5G5B5X1_UNORM),
|
||||
CONFIG(PIPE_FORMAT_R4G4B4A4_UNORM),
|
||||
CONFIG(PIPE_FORMAT_R4G4B4X4_UNORM),
|
||||
CONFIG(PIPE_FORMAT_B5G6R5_UNORM),
|
||||
CONFIG(PIPE_FORMAT_B5G5R5A1_UNORM),
|
||||
CONFIG(PIPE_FORMAT_B5G5R5X1_UNORM),
|
||||
CONFIG(PIPE_FORMAT_B4G4R4A4_UNORM),
|
||||
CONFIG(PIPE_FORMAT_B4G4R4X4_UNORM),
|
||||
};
|
||||
|
||||
#define RGB UTIL_FORMAT_COLORSPACE_RGB
|
||||
@@ -123,6 +129,7 @@ drilIndexConfigAttrib(const __DRIconfig *_config, int index,
|
||||
CASE(CONFORMANT, GL_TRUE);
|
||||
CASE(DOUBLE_BUFFER, config->doubleBufferMode);
|
||||
CASE(SAMPLES, config->samples);
|
||||
CASE(FRAMEBUFFER_SRGB_CAPABLE, config->sRGBCapable);
|
||||
|
||||
CASE(TRANSPARENT_TYPE, GLX_NONE);
|
||||
CASE(TRANSPARENT_INDEX_VALUE, GLX_NONE);
|
||||
@@ -272,14 +279,56 @@ drilCreateNewDrawable(__DRIscreen *psp,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define NUM_SAMPLE_COUNTS 7
|
||||
|
||||
static enum pipe_format
|
||||
fourcc_to_pipe_format(int fourcc)
|
||||
{
|
||||
switch (fourcc) {
|
||||
case DRM_FORMAT_RGB565: return PIPE_FORMAT_B5G6R5_UNORM;
|
||||
case DRM_FORMAT_XRGB8888: return PIPE_FORMAT_BGRX8888_UNORM;
|
||||
case DRM_FORMAT_ARGB8888: return PIPE_FORMAT_BGRA8888_UNORM;
|
||||
case DRM_FORMAT_ABGR8888: return PIPE_FORMAT_RGBA8888_UNORM;
|
||||
case DRM_FORMAT_XBGR8888: return PIPE_FORMAT_RGBX8888_UNORM;
|
||||
case DRM_FORMAT_XRGB2101010: return PIPE_FORMAT_B10G10R10X2_UNORM;
|
||||
case DRM_FORMAT_ARGB2101010: return PIPE_FORMAT_B10G10R10A2_UNORM;
|
||||
case DRM_FORMAT_XBGR2101010: return PIPE_FORMAT_R10G10B10X2_UNORM;
|
||||
case DRM_FORMAT_ABGR2101010: return PIPE_FORMAT_R10G10B10A2_UNORM;
|
||||
case DRM_FORMAT_XBGR16161616F: return PIPE_FORMAT_R16G16B16A16_FLOAT;
|
||||
case DRM_FORMAT_ABGR16161616F: return PIPE_FORMAT_R16G16B16X16_FLOAT;
|
||||
case DRM_FORMAT_ARGB1555: return PIPE_FORMAT_B5G5R5A1_UNORM;
|
||||
case DRM_FORMAT_ABGR1555: return PIPE_FORMAT_R5G5B5A1_UNORM;
|
||||
case DRM_FORMAT_ARGB4444: return PIPE_FORMAT_B4G4R4A4_UNORM;
|
||||
case DRM_FORMAT_ABGR4444: return PIPE_FORMAT_R4G4B4A4_UNORM;
|
||||
default: return PIPE_FORMAT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
add_srgb_config(struct gl_config **configs, unsigned c, enum pipe_format last_pformat, unsigned last_start)
|
||||
{
|
||||
enum pipe_format srgb = util_format_srgb(last_pformat);
|
||||
if (!srgb)
|
||||
return c;
|
||||
unsigned end = c;
|
||||
for (unsigned j = last_start; j < end; j++) {
|
||||
configs[c] = mem_dup(configs[j], sizeof(drilConfigs[j]));
|
||||
|
||||
struct gl_config *cfg = configs[c++];
|
||||
cfg->color_format = srgb;
|
||||
cfg->sRGBCapable = 1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/* DRI2 awfulness */
|
||||
static bool
|
||||
init_dri2_configs(int fd, const __DRIconfig **configs)
|
||||
static const __DRIconfig **
|
||||
init_dri2_configs(int fd)
|
||||
{
|
||||
void *egl = NULL;
|
||||
bool ret = false;
|
||||
struct gl_config **configs = NULL;
|
||||
unsigned c = 0;
|
||||
enum pipe_format last_pformat = 0;
|
||||
unsigned last_start = 0;
|
||||
|
||||
/* dlopen/dlsym to avoid linkage */
|
||||
egl = dlopen("libEGL.so.1", RTLD_LAZY | RTLD_LOCAL);
|
||||
@@ -290,7 +339,9 @@ init_dri2_configs(int fd, const __DRIconfig **configs)
|
||||
EGLDisplay (*peglGetPlatformDisplayEXT)(EGLenum, void *, const EGLint *) = peglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||
EGLDisplay (*peglInitialize)(EGLDisplay, int*, int*) = peglGetProcAddress("eglInitialize");
|
||||
void (*peglTerminate)(EGLDisplay) = peglGetProcAddress("eglTerminate");
|
||||
EGLBoolean (*peglChooseConfig)(EGLDisplay, EGLint const *, EGLConfig *, EGLint, EGLint*) = peglGetProcAddress("eglChooseConfig");
|
||||
EGLBoolean (*peglGetConfigs)(EGLDisplay, EGLConfig*, EGLint, EGLint*) = peglGetProcAddress("eglGetConfigs");
|
||||
EGLBoolean (*peglGetConfigAttrib)(EGLDisplay, EGLConfig, EGLint, EGLint *) = peglGetProcAddress("eglGetConfigAttrib");
|
||||
const char *(*peglQueryString)(EGLDisplay, EGLint) = peglGetProcAddress("eglQueryString");
|
||||
|
||||
/* try opening GBM for hardware driver info */
|
||||
struct gbm_device *gbm = gbm_create_device(fd);
|
||||
@@ -300,44 +351,66 @@ init_dri2_configs(int fd, const __DRIconfig **configs)
|
||||
EGLDisplay dpy = peglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, gbm, NULL);
|
||||
if (!dpy)
|
||||
goto out_gbm;
|
||||
|
||||
int maj, min;
|
||||
if (!peglInitialize(dpy, &maj, &min))
|
||||
goto out_gbm;
|
||||
|
||||
unsigned c = 0;
|
||||
const char *egl_extension_list = peglQueryString(dpy, EGL_EXTENSIONS);
|
||||
bool has_srgb = strstr(egl_extension_list, "EGL_KHR_gl_colorspace");
|
||||
|
||||
/* iterate over base configs and check for multisample support */
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(drilConfigs); i++) {
|
||||
unsigned num_samples[] = {
|
||||
0, 2, 4, 6, 8, 16, 32
|
||||
};
|
||||
static_assert(ARRAY_SIZE(num_samples) == NUM_SAMPLE_COUNTS, "sample count define needs updating");
|
||||
for (unsigned j = 0; j < ARRAY_SIZE(num_samples); j++) {
|
||||
const EGLint config_attribs[] = {
|
||||
EGL_RED_SIZE, SIZE(drilConfigs[i].color_format, RGB, 0),
|
||||
EGL_GREEN_SIZE, SIZE(drilConfigs[i].color_format, RGB, 1),
|
||||
EGL_BLUE_SIZE, SIZE(drilConfigs[i].color_format, RGB, 2),
|
||||
EGL_ALPHA_SIZE, SIZE(drilConfigs[i].color_format, RGB, 3),
|
||||
EGL_DEPTH_SIZE, SIZE(drilConfigs[i].zs_format, ZS, 0),
|
||||
EGL_STENCIL_SIZE, SIZE(drilConfigs[i].zs_format, ZS, 1),
|
||||
EGL_SAMPLES, num_samples[j],
|
||||
EGL_NONE
|
||||
};
|
||||
int num_configs = 0;
|
||||
if (peglChooseConfig(dpy, config_attribs, NULL, 0, &num_configs) && num_configs) {
|
||||
/* only copy supported configs */
|
||||
configs[c] = mem_dup(&drilConfigs[i], sizeof(drilConfigs[i]));
|
||||
int num_configs = 0;
|
||||
EGLConfig *eglconfigs = NULL;
|
||||
if (!peglGetConfigs(dpy, NULL, 0, &num_configs))
|
||||
goto out_egl;
|
||||
eglconfigs = malloc(sizeof(EGLConfig) * num_configs);
|
||||
/* overestimate: num_configs * doubleBuffer * sRGB + NULL */
|
||||
configs = calloc(num_configs * 2 * 2 + 1, sizeof(struct gl_config));
|
||||
if (!peglGetConfigs(dpy, eglconfigs, num_configs, &num_configs))
|
||||
goto out_egl;
|
||||
|
||||
/* hardcoded configs have samples=0, need to update */
|
||||
struct gl_config *cfg = (void*)configs[c];
|
||||
cfg->samples = num_samples[j];
|
||||
ret = true;
|
||||
c++;
|
||||
for (unsigned i = 0; i < num_configs; i++) {
|
||||
/* verify that this is the right format */
|
||||
EGLint format, depth, stencil, samples;
|
||||
|
||||
if (!peglGetConfigAttrib(dpy, eglconfigs[i], EGL_NATIVE_VISUAL_ID, &format) ||
|
||||
!peglGetConfigAttrib(dpy, eglconfigs[i], EGL_DEPTH_SIZE, &depth) ||
|
||||
!peglGetConfigAttrib(dpy, eglconfigs[i], EGL_STENCIL_SIZE, &stencil) ||
|
||||
!peglGetConfigAttrib(dpy, eglconfigs[i], EGL_SAMPLES, &samples))
|
||||
continue;
|
||||
|
||||
enum pipe_format pformat = fourcc_to_pipe_format(format);
|
||||
|
||||
/* srgb configs go after base configs */
|
||||
if (last_pformat && has_srgb && pformat != last_pformat)
|
||||
c = add_srgb_config(configs, c, last_pformat, last_start);
|
||||
/* tracking for the number of srgb configs to create */
|
||||
if (pformat != last_pformat)
|
||||
last_start = c;
|
||||
|
||||
for (unsigned j = 0; j < ARRAY_SIZE(drilConfigs); j++) {
|
||||
unsigned depth_size = SIZE(drilConfigs[j].zs_format, ZS, 0);
|
||||
unsigned stencil_size = SIZE(drilConfigs[j].zs_format, ZS, 1);
|
||||
/* only copy supported configs */
|
||||
if (pformat != drilConfigs[j].color_format || depth != depth_size || stencil != stencil_size)
|
||||
continue;
|
||||
|
||||
/* always create single-buffered and double-buffered */
|
||||
for (unsigned k = 0; k < 2; k++) {
|
||||
configs[c] = mem_dup(&drilConfigs[j], sizeof(drilConfigs[j]));
|
||||
|
||||
struct gl_config *cfg = configs[c++];
|
||||
cfg->samples = samples;
|
||||
cfg->doubleBufferMode = k;
|
||||
}
|
||||
break;
|
||||
}
|
||||
last_pformat = pformat;
|
||||
}
|
||||
|
||||
/* check last format for srgbness too */
|
||||
if (c && has_srgb)
|
||||
c = add_srgb_config(configs, c, last_pformat, last_start);
|
||||
out_egl:
|
||||
free(eglconfigs);
|
||||
/* don't forget cleanup */
|
||||
peglTerminate(dpy);
|
||||
|
||||
@@ -345,7 +418,10 @@ out_gbm:
|
||||
gbm_device_destroy(gbm);
|
||||
out:
|
||||
dlclose(egl);
|
||||
return ret;
|
||||
if (c)
|
||||
return (void*)configs;
|
||||
free(configs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static __DRIscreen *
|
||||
@@ -356,9 +432,12 @@ drilCreateNewScreen(int scrn, int fd,
|
||||
{
|
||||
/* multiply for possible 1/2/4/8/16/32 MSAA configs */
|
||||
// allocate an array of pointers
|
||||
const __DRIconfig **configs = calloc(ARRAY_SIZE(drilConfigs) * NUM_SAMPLE_COUNTS + 1, sizeof(void *));
|
||||
const __DRIconfig **configs = NULL;
|
||||
/* try dri2 if fd is valid */
|
||||
if (fd < 0 || !init_dri2_configs(fd, configs)) {
|
||||
if (fd >= 0)
|
||||
configs = init_dri2_configs(fd);
|
||||
if (!configs) {
|
||||
configs = calloc(ARRAY_SIZE(drilConfigs) + 1, sizeof(void *));
|
||||
// otherwise set configs to point to our config list
|
||||
for (int i = 0; i < ARRAY_SIZE(drilConfigs); i++) {
|
||||
configs[i] = mem_dup(&drilConfigs[i], sizeof(drilConfigs[i]));
|
||||
|
Reference in New Issue
Block a user