[Mesa-dev] [PATCH] dri: Add a way to query the driver for supported context flags

Adam Jackson ajax at redhat.com
Tue May 19 12:05:07 PDT 2015


xserver would like not to expose (say) ARB_robustness_isolation if the
driver doesn't actually support it, as it's pretty cruel to claim a
feature works but always throw BadFBConfig if you try to use it.  Add a
hook to the dri2 and swrast extensions to query the supported context
flags, initialize the set in InitScreen, and check that set in the
driver CreateContextAttribs hook instead of open-coding.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 include/GL/internal/dri_interface.h          | 20 ++++++++++++++++++--
 src/gallium/state_trackers/dri/dri2.c        |  6 ++++++
 src/gallium/state_trackers/dri/dri_context.c |  7 +------
 src/gallium/state_trackers/dri/drisw.c       |  3 +++
 src/mesa/drivers/dri/common/dri_util.c       | 12 ++++++++++--
 src/mesa/drivers/dri/common/dri_util.h       |  1 +
 src/mesa/drivers/dri/i915/intel_screen.c     |  3 ++-
 src/mesa/drivers/dri/i965/brw_context.c      | 11 +----------
 src/mesa/drivers/dri/i965/intel_screen.c     |  5 +++++
 9 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index c827bb6..2b360e6 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -785,13 +785,16 @@ struct __DRIlegacyExtensionRec {
 				      void *loaderPrivate);
 };
 
+typedef uint32_t
+(*__DRIcontextFlagsFunc)(__DRIscreen *screen);
+
 /**
  * This extension provides alternative screen, drawable and context
  * constructors for swrast DRI functionality.  This is used in
  * conjunction with the core extension.
  */
 #define __DRI_SWRAST "DRI_SWRast"
-#define __DRI_SWRAST_VERSION 4
+#define __DRI_SWRAST_VERSION 5
 
 struct __DRIswrastExtensionRec {
     __DRIextension base;
@@ -839,6 +842,12 @@ struct __DRIswrastExtensionRec {
                                     const __DRIconfig ***driver_configs,
                                     void *loaderPrivate);
 
+   /**
+    * Union of context flags accepted by createContextAttribs
+    *
+    * \since version 5
+    */
+    __DRIcontextFlagsFunc		contextFlags;
 };
 
 /** Common DRI function definitions, shared among DRI2 and Image extensions
@@ -953,7 +962,7 @@ struct __DRIdri2LoaderExtensionRec {
  * constructors for DRI2.
  */
 #define __DRI_DRI2 "DRI_DRI2"
-#define __DRI_DRI2_VERSION 4
+#define __DRI_DRI2_VERSION 5
 
 #define __DRI_API_OPENGL	0	/**< OpenGL compatibility profile */
 #define __DRI_API_GLES		1	/**< OpenGL ES 1.x */
@@ -1058,6 +1067,13 @@ struct __DRIdri2ExtensionRec {
     * \since version 4
     */
    __DRIcreateNewScreen2Func            createNewScreen2;
+
+   /**
+    * Union of context flags accepted by createContextAttribs
+    *
+    * \since version 5
+    */
+    __DRIcontextFlagsFunc		contextFlags;
 };
 
 
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index 792d565..7c277d7 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -1490,6 +1490,12 @@ dri2_init_screen(__DRIscreen * sPriv)
    else
       sPriv->extensions = dri_screen_extensions;
 
+   sPriv->context_flags = __DRI_CTX_FLAG_DEBUG |
+      __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
+
+   if (screen->has_reset_status_query)
+      sPriv->context_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
+
    /* dri_init_screen_helper checks pscreen for us */
 
 #if GALLIUM_STATIC_TARGETS
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 9f11b15..62ab603 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -56,13 +56,8 @@ dri_create_context(gl_api api, const struct gl_config * visual,
    struct st_context_iface *st_share = NULL;
    struct st_context_attribs attribs;
    enum st_context_error ctx_err = 0;
-   unsigned allowed_flags = __DRI_CTX_FLAG_DEBUG |
-                            __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
 
-   if (screen->has_reset_status_query)
-      allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
-
-   if (flags & ~allowed_flags) {
+   if (flags & ~sPriv->context_flags) {
       *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
       goto fail;
    }
diff --git a/src/gallium/state_trackers/dri/drisw.c b/src/gallium/state_trackers/dri/drisw.c
index 4a2c1bb..7b2daa9 100644
--- a/src/gallium/state_trackers/dri/drisw.c
+++ b/src/gallium/state_trackers/dri/drisw.c
@@ -361,6 +361,9 @@ drisw_init_screen(__DRIscreen * sPriv)
    sPriv->driverPrivate = (void *)screen;
    sPriv->extensions = drisw_screen_extensions;
 
+   sPriv->context_flags = __DRI_CTX_FLAG_DEBUG |
+      __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
+
    pscreen = drisw_create_screen(&drisw_lf);
    /* dri_init_screen_helper checks pscreen for us */
 
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index d6e875f..90b2d6d 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -471,6 +471,12 @@ driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
                                      config, shared, data);
 }
 
+static uint32_t
+driContextFlags(__DRIscreen *screen)
+{
+    return screen->context_flags;
+}
+
 /**
  * Destroy the per-context private information.
  * 
@@ -753,7 +759,7 @@ const __DRIcoreExtension driCoreExtension = {
 
 /** DRI2 interface */
 const __DRIdri2Extension driDRI2Extension = {
-    .base = { __DRI_DRI2, 4 },
+    .base = { __DRI_DRI2, 5 },
 
     .createNewScreen            = dri2CreateNewScreen,
     .createNewDrawable          = driCreateNewDrawable,
@@ -764,16 +770,18 @@ const __DRIdri2Extension driDRI2Extension = {
     .releaseBuffer              = dri2ReleaseBuffer,
     .createContextAttribs       = driCreateContextAttribs,
     .createNewScreen2           = driCreateNewScreen2,
+    .contextFlags               = driContextFlags,
 };
 
 const __DRIswrastExtension driSWRastExtension = {
-    .base = { __DRI_SWRAST, 4 },
+    .base = { __DRI_SWRAST, 5 },
 
     .createNewScreen            = driSWRastCreateNewScreen,
     .createNewDrawable          = driCreateNewDrawable,
     .createNewContextForAPI     = driCreateNewContextForAPI,
     .createContextAttribs       = driCreateContextAttribs,
     .createNewScreen2           = driSWRastCreateNewScreen2,
+    .contextFlags               = driContextFlags,
 };
 
 const __DRI2configQueryExtension dri2ConfigQueryExtension = {
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 1138bf1..3baa949 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -187,6 +187,7 @@ struct __DRIscreenRec {
     driOptionCache optionCache;
 
     unsigned int api_mask;
+    uint32_t context_flags;
 };
 
 /**
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 77af328..19c5cd3 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -959,7 +959,7 @@ intelCreateContext(gl_api api,
    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    struct intel_screen *intelScreen = sPriv->driverPrivate;
 
-   if (flags & ~__DRI_CTX_FLAG_DEBUG) {
+   if (flags & ~sPriv->context_flags) {
       *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
       return false;
    }
@@ -1188,6 +1188,7 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
    set_max_gl_versions(intelScreen);
 
    psp->extensions = intelScreenExtensions;
+   psp->context_flags = __DRI_CTX_FLAG_DEBUG;
 
    return (const __DRIconfig**) intel_screen_make_configs(psp);
 }
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index ea56859..36e5b4c 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -713,16 +713,7 @@ brwCreateContext(gl_api api,
    const struct brw_device_info *devinfo = screen->devinfo;
    struct dd_function_table functions;
 
-   /* Only allow the __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS flag if the kernel
-    * provides us with context reset notifications.
-    */
-   uint32_t allowed_flags = __DRI_CTX_FLAG_DEBUG
-      | __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
-
-   if (screen->has_context_reset_notification)
-      allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
-
-   if (flags & ~allowed_flags) {
+   if (flags & ~sPriv->context_flags) {
       *dri_ctx_error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
       return false;
    }
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 896a125..92dd9d0 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -1417,6 +1417,11 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
    psp->extensions = !intelScreen->has_context_reset_notification
       ? intelScreenExtensions : intelRobustScreenExtensions;
 
+   psp->context_flags =__DRI_CTX_FLAG_DEBUG
+      | __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
+   if (intelScreen->has_context_reset_notification)
+      psp->context_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
+
    intelScreen->compiler = brw_compiler_create(intelScreen,
                                                intelScreen->devinfo);
 
-- 
2.4.1



More information about the mesa-dev mailing list