X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fcommon%2Fdri_util.c;h=5cfa2f8ca4f1a7e78c9459ac19ccf3df9c5c5113;hb=a4fca2448422f52508cf7c7948102299c2db63d6;hp=db44eede651168185ee04a53f4557631aa508c37;hpb=95bd8a332d1c3f868d8e4ff454fb308acd9beed9;p=mesa.git diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index db44eede651..5cfa2f8ca4f 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -40,18 +40,16 @@ #include -#ifndef __NOT_HAVE_DRM_H -#include -#endif #include "dri_util.h" #include "utils.h" #include "xmlpool.h" -#include "../glsl/glsl_parser_extras.h" #include "main/mtypes.h" +#include "main/framebuffer.h" #include "main/version.h" +#include "main/errors.h" #include "main/macros.h" -PUBLIC const char __dri2ConfigOptions[] = +const char __dri2ConfigOptions[] = DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1) @@ -78,9 +76,28 @@ setupLoaderExtensions(__DRIscreen *psp, psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i]; if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0) psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_IMAGE_LOADER) == 0) + psp->image.loader = (__DRIimageLoaderExtension *) extensions[i]; } } +/** + * This pointer determines which driver API we'll use in the case of the + * loader not passing us an explicit driver extensions list (that would, + * itself, contain a pointer to a driver API.) + * + * A driver's driDriverGetExtensions_drivername() can update this pointer to + * what it's returning, and a loader that is ignorant of createNewScreen2() + * will get the correct driver screen created, as long as no other + * driDriverGetExtensions() happened in between the first one and the + * createNewScreen(). + * + * This allows the X Server to not require the significant dri_interface.h + * updates for doing createNewScreen2(), which would discourage backporting of + * the X Server patches to support the new loader interface. + */ +const struct __DriverAPIRec *globalDriverAPI = &driDriverAPI; + /** * This is the first entrypoint in the driver called by the DRI driver loader * after dlopen()ing it. @@ -89,9 +106,10 @@ setupLoaderExtensions(__DRIscreen *psp, * Display. */ static __DRIscreen * -dri2CreateNewScreen(int scrn, int fd, - const __DRIextension **extensions, - const __DRIconfig ***driver_configs, void *data) +driCreateNewScreen2(int scrn, int fd, + const __DRIextension **extensions, + const __DRIextension **driver_extensions, + const __DRIconfig ***driver_configs, void *data) { static const __DRIextension *emptyExtensionList[] = { NULL }; __DRIscreen *psp; @@ -100,21 +118,22 @@ dri2CreateNewScreen(int scrn, int fd, if (!psp) return NULL; - psp->driver = &driDriverAPI; + /* By default, use the global driDriverAPI symbol (non-megadrivers). */ + psp->driver = globalDriverAPI; - setupLoaderExtensions(psp, extensions); - -#ifndef __NOT_HAVE_DRM_H - if (fd != -1) { - drmVersionPtr version = drmGetVersion(fd); - if (version) { - psp->drm_version.major = version->version_major; - psp->drm_version.minor = version->version_minor; - psp->drm_version.patch = version->version_patchlevel; - drmFreeVersion(version); + /* If the driver exposes its vtable through its extensions list + * (megadrivers), use that instead. + */ + if (driver_extensions) { + for (int i = 0; driver_extensions[i]; i++) { + if (strcmp(driver_extensions[i]->name, __DRI_DRIVER_VTABLE) == 0) { + psp->driver = + ((__DRIDriverVtableExtension *)driver_extensions[i])->vtable; + } } } -#endif + + setupLoaderExtensions(psp, extensions); psp->loaderPrivate = data; @@ -128,16 +147,26 @@ dri2CreateNewScreen(int scrn, int fd, return NULL; } - int gl_version_override = _mesa_get_gl_version_override(); - if (gl_version_override >= 31) { - psp->max_gl_core_version = MAX2(psp->max_gl_core_version, - gl_version_override); - } else { - psp->max_gl_compat_version = MAX2(psp->max_gl_compat_version, - gl_version_override); + struct gl_constants consts = { 0 }; + gl_api api; + unsigned version; + + api = API_OPENGLES2; + if (_mesa_override_gl_version_contextless(&consts, &api, &version)) + psp->max_gl_es2_version = version; + + api = API_OPENGL_COMPAT; + if (_mesa_override_gl_version_contextless(&consts, &api, &version)) { + if (api == API_OPENGL_CORE) { + psp->max_gl_core_version = version; + } else { + psp->max_gl_compat_version = version; + } } - psp->api_mask = (1 << __DRI_API_OPENGL); + psp->api_mask = 0; + if (psp->max_gl_compat_version > 0) + psp->api_mask |= (1 << __DRI_API_OPENGL); if (psp->max_gl_core_version > 0) psp->api_mask |= (1 << __DRI_API_OPENGL_CORE); if (psp->max_gl_es1_version > 0) @@ -154,12 +183,31 @@ dri2CreateNewScreen(int scrn, int fd, return psp; } +static __DRIscreen * +dri2CreateNewScreen(int scrn, int fd, + const __DRIextension **extensions, + const __DRIconfig ***driver_configs, void *data) +{ + return driCreateNewScreen2(scrn, fd, extensions, NULL, + driver_configs, data); +} + /** swrast driver createNewScreen entrypoint. */ static __DRIscreen * -driCreateNewScreen(int scrn, const __DRIextension **extensions, - const __DRIconfig ***driver_configs, void *data) +driSWRastCreateNewScreen(int scrn, const __DRIextension **extensions, + const __DRIconfig ***driver_configs, void *data) +{ + return driCreateNewScreen2(scrn, -1, extensions, NULL, + driver_configs, data); +} + +static __DRIscreen * +driSWRastCreateNewScreen2(int scrn, const __DRIextension **extensions, + const __DRIextension **driver_extensions, + const __DRIconfig ***driver_configs, void *data) { - return dri2CreateNewScreen(scrn, -1, extensions, driver_configs, data); + return driCreateNewScreen2(scrn, -1, extensions, driver_extensions, + driver_configs, data); } /** @@ -177,8 +225,6 @@ static void driDestroyScreen(__DRIscreen *psp) * stream open to the X-server anymore. */ - _mesa_destroy_shader_compiler(); - psp->driver->DestroyScreen(psp); driDestroyOptionCache(&psp->optionCache); @@ -241,13 +287,13 @@ validate_context_version(__DRIscreen *screen, /*@{*/ static __DRIcontext * -dri2CreateContextAttribs(__DRIscreen *screen, int api, - const __DRIconfig *config, - __DRIcontext *shared, - unsigned num_attribs, - const uint32_t *attribs, - unsigned *error, - void *data) +driCreateContextAttribs(__DRIscreen *screen, int api, + const __DRIconfig *config, + __DRIcontext *shared, + unsigned num_attribs, + const uint32_t *attribs, + unsigned *error, + void *data) { __DRIcontext *context; const struct gl_config *modes = (config != NULL) ? &config->modes : NULL; @@ -256,6 +302,7 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, unsigned major_version = 1; unsigned minor_version = 0; uint32_t flags = 0; + bool notify_reset = false; assert((num_attribs == 0) || (attribs != NULL)); @@ -294,6 +341,10 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, case __DRI_CTX_ATTRIB_FLAGS: flags = attribs[i * 2 + 1]; break; + case __DRI_CTX_ATTRIB_RESET_STRATEGY: + notify_reset = (attribs[i * 2 + 1] + != __DRI_CTX_RESET_NO_NOTIFICATION); + break; default: /* We can't create a context that satisfies the requirements of an * attribute that we don't understand. Return failure. @@ -318,19 +369,17 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, return NULL; } - /* The EGL_KHR_create_context spec says: + /* The latest version of EGL_KHR_create_context spec says: * - * "Flags are only defined for OpenGL context creation, and specifying - * a flags value other than zero for other types of contexts, - * including OpenGL ES contexts, will generate an error." + * "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in + * EGL_CONTEXT_FLAGS_KHR, then a will be created. + * [...] This bit is supported for OpenGL and OpenGL ES contexts. * - * The GLX_EXT_create_context_es2_profile specification doesn't say - * anything specific about this case. However, none of the known flags - * have any meaning in an ES context, so this seems safe. + * None of the other flags have any meaning in an ES context, so this seems safe. */ if (mesa_api != API_OPENGL_COMPAT && mesa_api != API_OPENGL_CORE - && flags != 0) { + && (flags & ~__DRI_CTX_FLAG_DEBUG)) { *error = __DRI_CTX_ERROR_BAD_FLAG; return NULL; } @@ -350,8 +399,10 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, mesa_api = API_OPENGL_CORE; } - if ((flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE)) - != 0) { + const uint32_t allowed_flags = (__DRI_CTX_FLAG_DEBUG + | __DRI_CTX_FLAG_FORWARD_COMPATIBLE + | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS); + if (flags & ~allowed_flags) { *error = __DRI_CTX_ERROR_UNKNOWN_FLAG; return NULL; } @@ -374,40 +425,43 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, if (!screen->driver->CreateContext(mesa_api, modes, context, major_version, minor_version, - flags, error, shareCtx) ) { + flags, notify_reset, error, shareCtx)) { free(context); return NULL; } - struct gl_context *ctx = context->driverPrivate; + *error = __DRI_CTX_ERROR_SUCCESS; + return context; +} + +void +driContextSetFlags(struct gl_context *ctx, uint32_t flags) +{ if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) { + _mesa_set_debug_state_int(ctx, GL_DEBUG_OUTPUT, GL_TRUE); ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; - ctx->Debug.DebugOutput = GL_TRUE; } - - *error = __DRI_CTX_ERROR_SUCCESS; - return context; } static __DRIcontext * -dri2CreateNewContextForAPI(__DRIscreen *screen, int api, - const __DRIconfig *config, - __DRIcontext *shared, void *data) +driCreateNewContextForAPI(__DRIscreen *screen, int api, + const __DRIconfig *config, + __DRIcontext *shared, void *data) { unsigned error; - return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL, - &error, data); + return driCreateContextAttribs(screen, api, config, shared, 0, NULL, + &error, data); } static __DRIcontext * -dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config, - __DRIcontext *shared, void *data) +driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config, + __DRIcontext *shared, void *data) { - return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL, - config, shared, data); + return driCreateNewContextForAPI(screen, __DRI_API_OPENGL, + config, shared, data); } /** @@ -506,6 +560,12 @@ static int driUnbindContext(__DRIcontext *pcp) if (pcp == NULL) return GL_FALSE; + /* + ** Call driUnbindContext before checking for valid drawables + ** to handle surfaceless contexts properly. + */ + pcp->driScreenPriv->driver->UnbindContext(pcp); + pdp = pcp->driDrawablePriv; prp = pcp->driReadablePriv; @@ -513,8 +573,6 @@ static int driUnbindContext(__DRIcontext *pcp) if (!pdp && !prp) return GL_TRUE; - pcp->driScreenPriv->driver->UnbindContext(pcp); - assert(pdp); if (pdp->refcount == 0) { /* ERROR!!! */ @@ -559,9 +617,9 @@ static void dri_put_drawable(__DRIdrawable *pdp) } static __DRIdrawable * -dri2CreateNewDrawable(__DRIscreen *screen, - const __DRIconfig *config, - void *data) +driCreateNewDrawable(__DRIscreen *screen, + const __DRIconfig *config, + void *data) { __DRIdrawable *pdraw; @@ -614,7 +672,7 @@ dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer) static int -dri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val) +dri2ConfigQueryb(__DRIscreen *screen, const char *var, unsigned char *val) { if (!driCheckOption(&screen->optionCache, var, DRI_BOOL)) return -1; @@ -625,7 +683,7 @@ dri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val) } static int -dri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val) +dri2ConfigQueryi(__DRIscreen *screen, const char *var, int *val) { if (!driCheckOption(&screen->optionCache, var, DRI_INT) && !driCheckOption(&screen->optionCache, var, DRI_ENUM)) @@ -637,7 +695,7 @@ dri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val) } static int -dri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val) +dri2ConfigQueryf(__DRIscreen *screen, const char *var, float *val) { if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT)) return -1; @@ -648,7 +706,7 @@ dri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val) } static unsigned int -dri2GetAPIMask(__DRIscreen *screen) +driGetAPIMask(__DRIscreen *screen) { return screen->api_mask; } @@ -669,7 +727,7 @@ driSwapBuffers(__DRIdrawable *pdp) /** Core interface */ const __DRIcoreExtension driCoreExtension = { - .base = { __DRI_CORE, __DRI_CORE_VERSION }, + .base = { __DRI_CORE, 1 }, .createNewScreen = NULL, .destroyScreen = driDestroyScreen, @@ -679,7 +737,7 @@ const __DRIcoreExtension driCoreExtension = { .createNewDrawable = NULL, .destroyDrawable = driDestroyDrawable, .swapBuffers = driSwapBuffers, /* swrast */ - .createNewContext = dri2CreateNewContext, /* swrast */ + .createNewContext = driCreateNewContext, /* swrast */ .copyContext = driCopyContext, .destroyContext = driDestroyContext, .bindContext = driBindContext, @@ -688,28 +746,31 @@ const __DRIcoreExtension driCoreExtension = { /** DRI2 interface */ const __DRIdri2Extension driDRI2Extension = { - .base = { __DRI_DRI2, 3 }, + .base = { __DRI_DRI2, 4 }, .createNewScreen = dri2CreateNewScreen, - .createNewDrawable = dri2CreateNewDrawable, - .createNewContext = dri2CreateNewContext, - .getAPIMask = dri2GetAPIMask, - .createNewContextForAPI = dri2CreateNewContextForAPI, + .createNewDrawable = driCreateNewDrawable, + .createNewContext = driCreateNewContext, + .getAPIMask = driGetAPIMask, + .createNewContextForAPI = driCreateNewContextForAPI, .allocateBuffer = dri2AllocateBuffer, .releaseBuffer = dri2ReleaseBuffer, - .createContextAttribs = dri2CreateContextAttribs + .createContextAttribs = driCreateContextAttribs, + .createNewScreen2 = driCreateNewScreen2, }; const __DRIswrastExtension driSWRastExtension = { - { __DRI_SWRAST, __DRI_SWRAST_VERSION }, - driCreateNewScreen, - dri2CreateNewDrawable, - dri2CreateNewContextForAPI, - dri2CreateContextAttribs + .base = { __DRI_SWRAST, 4 }, + + .createNewScreen = driSWRastCreateNewScreen, + .createNewDrawable = driCreateNewDrawable, + .createNewContextForAPI = driCreateNewContextForAPI, + .createContextAttribs = driCreateContextAttribs, + .createNewScreen2 = driSWRastCreateNewScreen2, }; const __DRI2configQueryExtension dri2ConfigQueryExtension = { - .base = { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION }, + .base = { __DRI2_CONFIG_QUERY, 1 }, .configQueryb = dri2ConfigQueryb, .configQueryi = dri2ConfigQueryi, @@ -733,10 +794,98 @@ driUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv) { struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate; if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) { - ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h); + _mesa_resize_framebuffer(ctx, fb, dPriv->w, dPriv->h); /* if the driver needs the hw lock for ResizeBuffers, the drawable might have changed again by now */ assert(fb->Width == dPriv->w); assert(fb->Height == dPriv->h); } } + +uint32_t +driGLFormatToImageFormat(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_B5G6R5_UNORM: + return __DRI_IMAGE_FORMAT_RGB565; + case MESA_FORMAT_B8G8R8X8_UNORM: + return __DRI_IMAGE_FORMAT_XRGB8888; + case MESA_FORMAT_B10G10R10A2_UNORM: + return __DRI_IMAGE_FORMAT_ARGB2101010; + case MESA_FORMAT_B10G10R10X2_UNORM: + return __DRI_IMAGE_FORMAT_XRGB2101010; + case MESA_FORMAT_B8G8R8A8_UNORM: + return __DRI_IMAGE_FORMAT_ARGB8888; + case MESA_FORMAT_R8G8B8A8_UNORM: + return __DRI_IMAGE_FORMAT_ABGR8888; + case MESA_FORMAT_R8G8B8X8_UNORM: + return __DRI_IMAGE_FORMAT_XBGR8888; + case MESA_FORMAT_R_UNORM8: + return __DRI_IMAGE_FORMAT_R8; + case MESA_FORMAT_R8G8_UNORM: + return __DRI_IMAGE_FORMAT_GR88; + case MESA_FORMAT_NONE: + return __DRI_IMAGE_FORMAT_NONE; + case MESA_FORMAT_B8G8R8A8_SRGB: + return __DRI_IMAGE_FORMAT_SARGB8; + default: + return 0; + } +} + +mesa_format +driImageFormatToGLFormat(uint32_t image_format) +{ + switch (image_format) { + case __DRI_IMAGE_FORMAT_RGB565: + return MESA_FORMAT_B5G6R5_UNORM; + case __DRI_IMAGE_FORMAT_XRGB8888: + return MESA_FORMAT_B8G8R8X8_UNORM; + case __DRI_IMAGE_FORMAT_ARGB2101010: + return MESA_FORMAT_B10G10R10A2_UNORM; + case __DRI_IMAGE_FORMAT_XRGB2101010: + return MESA_FORMAT_B10G10R10X2_UNORM; + case __DRI_IMAGE_FORMAT_ARGB8888: + return MESA_FORMAT_B8G8R8A8_UNORM; + case __DRI_IMAGE_FORMAT_ABGR8888: + return MESA_FORMAT_R8G8B8A8_UNORM; + case __DRI_IMAGE_FORMAT_XBGR8888: + return MESA_FORMAT_R8G8B8X8_UNORM; + case __DRI_IMAGE_FORMAT_R8: + return MESA_FORMAT_R_UNORM8; + case __DRI_IMAGE_FORMAT_GR88: + return MESA_FORMAT_R8G8_UNORM; + case __DRI_IMAGE_FORMAT_SARGB8: + return MESA_FORMAT_B8G8R8A8_SRGB; + case __DRI_IMAGE_FORMAT_NONE: + return MESA_FORMAT_NONE; + default: + return MESA_FORMAT_NONE; + } +} + +/** Image driver interface */ +const __DRIimageDriverExtension driImageDriverExtension = { + .base = { __DRI_IMAGE_DRIVER, 1 }, + + .createNewScreen2 = driCreateNewScreen2, + .createNewDrawable = driCreateNewDrawable, + .getAPIMask = driGetAPIMask, + .createContextAttribs = driCreateContextAttribs, +}; + +/* swrast copy sub buffer entrypoint. */ +static void driCopySubBuffer(__DRIdrawable *pdp, int x, int y, + int w, int h) +{ + assert(pdp->driScreenPriv->swrast_loader); + + pdp->driScreenPriv->driver->CopySubBuffer(pdp, x, y, w, h); +} + +/* for swrast only */ +const __DRIcopySubBufferExtension driCopySubBufferExtension = { + .base = { __DRI_COPY_SUB_BUFFER, 1 }, + + .copySubBuffer = driCopySubBuffer, +};