[Mesa-dev] [RFC 1/6] dri: Support 64 bit rgba masks

Kevin Strasser kevin.strasser at intel.com
Fri Jan 4 21:56:27 UTC 2019


The dri core api was written with the assumption that all attribute values
would fit into 32 bits. This limitation means the config handlers can't
accept 64 bpp formats. Reserve 64 bits for rgba masks and add new
attributes that allow access to the upper 32 bits.

Signed-off-by: Kevin Strasser <kevin.strasser at intel.com>
---
 include/GL/internal/dri_interface.h         |  6 ++-
 src/egl/drivers/dri2/egl_dri2.c             | 28 +++++++++---
 src/egl/drivers/dri2/egl_dri2.h             |  6 +--
 src/egl/drivers/dri2/platform_android.c     |  2 +-
 src/egl/drivers/dri2/platform_drm.c         | 67 ++++++++++++++++++++++-------
 src/egl/drivers/dri2/platform_surfaceless.c |  2 +-
 src/egl/drivers/dri2/platform_wayland.c     |  2 +-
 src/egl/drivers/dri2/platform_x11.c         |  6 +--
 src/gbm/backends/dri/gbm_driint.h           |  8 ++--
 src/glx/glxconfig.h                         |  2 +-
 src/mesa/drivers/dri/common/utils.c         | 16 ++++++-
 src/mesa/main/mtypes.h                      |  2 +-
 12 files changed, 108 insertions(+), 39 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 072f379..c5761c4 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -747,7 +747,11 @@ struct __DRIuseInvalidateExtensionRec {
 #define __DRI_ATTRIB_YINVERTED			47
 #define __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE	48
 #define __DRI_ATTRIB_MUTABLE_RENDER_BUFFER	49 /* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR */
-#define __DRI_ATTRIB_MAX			50
+#define __DRI_ATTRIB_RED_MASK_HI		50
+#define __DRI_ATTRIB_GREEN_MASK_HI		51
+#define __DRI_ATTRIB_BLUE_MASK_HI		52
+#define __DRI_ATTRIB_ALPHA_MASK_HI		53
+#define __DRI_ATTRIB_MAX			54
 
 /* __DRI_ATTRIB_RENDER_TYPE */
 #define __DRI_ATTRIB_RGBA_BIT			0x01	
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 0be9235..d19950d 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -179,7 +179,7 @@ dri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria)
 struct dri2_egl_config *
 dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
                 EGLint surface_type, const EGLint *attr_list,
-                const unsigned int *rgba_masks)
+                const unsigned long long int *rgba_masks)
 {
    struct dri2_egl_config *conf;
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
@@ -187,7 +187,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
    unsigned int attrib, value, double_buffer;
    bool srgb = false;
    EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
-   unsigned int dri_masks[4] = { 0, 0, 0, 0 };
+   unsigned long long int dri_masks[4] = { 0, 0, 0, 0 };
    _EGLConfig *matching_config;
    EGLint num_configs = 0;
    EGLint config_id;
@@ -234,19 +234,35 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
          break;
 
       case __DRI_ATTRIB_RED_MASK:
-         dri_masks[0] = value;
+         dri_masks[0] |= value;
+         break;
+
+      case __DRI_ATTRIB_RED_MASK_HI:
+         dri_masks[0] |= (unsigned long long int)value << 32;
          break;
 
       case __DRI_ATTRIB_GREEN_MASK:
-         dri_masks[1] = value;
+         dri_masks[1] |= value;
+         break;
+
+      case __DRI_ATTRIB_GREEN_MASK_HI:
+         dri_masks[1] |= (unsigned long long int)value << 32;
          break;
 
       case __DRI_ATTRIB_BLUE_MASK:
-         dri_masks[2] = value;
+         dri_masks[2] |= value;
+         break;
+
+      case __DRI_ATTRIB_BLUE_MASK_HI:
+         dri_masks[2] |= (unsigned long long int)value << 32;
          break;
 
       case __DRI_ATTRIB_ALPHA_MASK:
-         dri_masks[3] = value;
+         dri_masks[3] |= value;
+         break;
+
+      case __DRI_ATTRIB_ALPHA_MASK_HI:
+         dri_masks[3] |= (unsigned long long int)value << 32;
          break;
 
       case __DRI_ATTRIB_ACCUM_RED_SIZE:
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 4abe1ba..3916c68 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -404,7 +404,7 @@ dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data);
 struct dri2_egl_config *
 dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
                 EGLint surface_type, const EGLint *attr_list,
-                const unsigned int *rgba_masks);
+                const unsigned long long int *rgba_masks);
 
 _EGLImage *
 dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
@@ -420,7 +420,7 @@ EGLBoolean
 dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp);
 void
 dri2_teardown_x11(struct dri2_egl_display *dri2_dpy);
-unsigned int
+unsigned long long int
 dri2_x11_get_red_mask_for_depth(struct dri2_egl_display *dri2_dpy, int depth);
 #else
 static inline EGLBoolean
@@ -430,7 +430,7 @@ dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
 }
 static inline void
 dri2_teardown_x11(struct dri2_egl_display *dri2_dpy) {}
-static inline unsigned int
+static inline unsigned long long int
 dri2_x11_get_red_mask_for_depth(struct dri2_egl_display *dri2_dpy, int depth)
 {
    return 0;
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index 366a9ec..c385507 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -1136,7 +1136,7 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
    static const struct {
       int format;
-      unsigned int rgba_masks[4];
+      unsigned long long int rgba_masks[4];
    } visuals[] = {
       { HAL_PIXEL_FORMAT_RGBA_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 } },
       { HAL_PIXEL_FORMAT_RGBX_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 } },
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index c1ab1c9..47563d6 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -96,7 +96,8 @@ dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy,
                               struct gbm_surface *surface)
 {
    const struct gbm_dri_visual *visual = NULL;
-   unsigned int red, green, blue, alpha;
+   unsigned long long int red, green, blue, alpha;
+   unsigned int mask_hi = 0, mask_lo, render_type;
    int i;
 
    /* Check that the EGLConfig being used to render to the surface is
@@ -104,10 +105,29 @@ dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy,
     * otherwise-compatible formats is relatively common, explicitly allow
     * this.
     */
-   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_RED_MASK, &red);
-   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_MASK, &green);
-   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_MASK, &blue);
-   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_MASK, &alpha);
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_RED_MASK_HI,
+                                   &mask_hi);
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_RED_MASK,
+                                   &mask_lo);
+   red = (unsigned long long int)mask_hi << 32 | mask_lo;
+
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_MASK_HI,
+                                   &mask_hi);
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_MASK,
+                                   &mask_lo);
+   green = (unsigned long long int)mask_hi << 32 | mask_lo;
+
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_MASK_HI,
+                                   &mask_hi);
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_MASK,
+                                   &mask_lo);
+   blue = (unsigned long long int)mask_hi << 32 | mask_lo;
+
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_MASK_HI,
+                                   &mask_hi);
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_MASK,
+                                   &mask_lo);
+   alpha = (unsigned long long int)mask_hi << 32 | mask_lo;
 
    for (i = 0; i < dri2_dpy->gbm_dri->num_visuals; i++) {
       visual = &dri2_dpy->gbm_dri->visual_table[i];
@@ -627,16 +647,33 @@ drm_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
    memset(format_count, 0, num_visuals * sizeof(unsigned int));
 
    for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
-      unsigned int red, green, blue, alpha;
-
-      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
-                                      __DRI_ATTRIB_RED_MASK, &red);
-      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
-                                      __DRI_ATTRIB_GREEN_MASK, &green);
-      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
-                                      __DRI_ATTRIB_BLUE_MASK, &blue);
-      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
-                                      __DRI_ATTRIB_ALPHA_MASK, &alpha);
+      const __DRIconfig *config = dri2_dpy->driver_configs[i];
+      unsigned long long int red, green, blue, alpha;
+      unsigned int mask_hi = 0, mask_lo;
+
+      dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_RED_MASK_HI,
+                                      &mask_hi);
+      dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_RED_MASK,
+                                      &mask_lo);
+      red = (unsigned long long int)mask_hi << 32 | mask_lo;
+
+      dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_MASK_HI,
+                                      &mask_hi);
+      dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_MASK,
+                                      &mask_lo);
+      green = (unsigned long long int)mask_hi << 32 | mask_lo;
+
+      dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_MASK_HI,
+                                      &mask_hi);
+      dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_MASK,
+                                      &mask_lo);
+      blue = (unsigned long long int)mask_hi << 32 | mask_lo;
+
+      dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_MASK_HI,
+                                      &mask_hi);
+      dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_MASK,
+                                      &mask_lo);
+      alpha = (unsigned long long int)mask_hi << 32 | mask_lo;
 
       for (unsigned j = 0; j < num_visuals; j++) {
          struct dri2_egl_config *dri2_conf;
diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c
index f980956..586539e 100644
--- a/src/egl/drivers/dri2/platform_surfaceless.c
+++ b/src/egl/drivers/dri2/platform_surfaceless.c
@@ -186,7 +186,7 @@ surfaceless_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
    static const struct {
       const char *format_name;
-      unsigned int rgba_masks[4];
+      unsigned long long int rgba_masks[4];
    } visuals[] = {
       { "ARGB8888", { 0xff0000, 0xff00, 0xff, 0xff000000 } },
       { "RGB888",   { 0xff0000, 0xff00, 0xff, 0x0 } },
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 34e09d7..405f044 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -60,7 +60,7 @@ static const struct dri2_wl_visual {
    uint32_t wl_shm_format;
    int dri_image_format;
    int bpp;
-   unsigned int rgba_masks[4];
+   unsigned long long int rgba_masks[4];
 } dri2_wl_visuals[] = {
    {
      "XRGB2101010",
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index 4684c9f..83b99b1 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -232,7 +232,7 @@ get_xcb_visualtype_for_depth(struct dri2_egl_display *dri2_dpy, int depth)
 }
 
 /* Get red channel mask for given depth. */
-unsigned int
+unsigned long long int
 dri2_x11_get_red_mask_for_depth(struct dri2_egl_display *dri2_dpy, int depth)
 {
    xcb_visualtype_t *visual = get_xcb_visualtype_for_depth(dri2_dpy, depth);
@@ -806,7 +806,7 @@ dri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
                     EGL_NONE
             };
 
-            unsigned int rgba_masks[4] = {
+            unsigned long long int rgba_masks[4] = {
                visuals[i].red_mask,
                visuals[i].green_mask,
                visuals[i].blue_mask,
@@ -830,7 +830,7 @@ dri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
              * EGLConfigs! */
             if (d.data->depth == 24 || d.data->depth == 30) {
                rgba_masks[3] =
-                  ~(rgba_masks[0] | rgba_masks[1] | rgba_masks[2]);
+                  ~(unsigned int)(rgba_masks[0] | rgba_masks[1] | rgba_masks[2]);
                dri2_conf = dri2_add_config(disp, config, config_count + 1,
                                            surface_type, config_attrs,
                                            rgba_masks);
diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h
index 8497be3..0640198 100644
--- a/src/gbm/backends/dri/gbm_driint.h
+++ b/src/gbm/backends/dri/gbm_driint.h
@@ -44,10 +44,10 @@ struct gbm_dri_visual {
    uint32_t gbm_format;
    int dri_image_format;
    struct {
-      uint32_t red;
-      uint32_t green;
-      uint32_t blue;
-      uint32_t alpha;
+      uint64_t red;
+      uint64_t green;
+      uint64_t blue;
+      uint64_t alpha;
    } rgba_masks;
 };
 
diff --git a/src/glx/glxconfig.h b/src/glx/glxconfig.h
index 2f1074c..b943b61 100644
--- a/src/glx/glxconfig.h
+++ b/src/glx/glxconfig.h
@@ -40,7 +40,7 @@ struct glx_config {
     GLuint stereoMode;
 
     GLint redBits, greenBits, blueBits, alphaBits;	/* bits per comp */
-    GLuint redMask, greenMask, blueMask, alphaMask;
+    GLuint64 redMask, greenMask, blueMask, alphaMask;
     GLint rgbBits;		/* total bits for rgb */
     GLint indexBits;		/* total bits for colorindex */
 
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index 5a66bcf..c7e5b84 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -181,7 +181,7 @@ driCreateConfigs(mesa_format format,
 		 GLboolean enable_accum, GLboolean color_depth_match,
 		 GLboolean mutable_render_buffer)
 {
-   static const uint32_t masks_table[][4] = {
+   static const uint64_t masks_table[][4] = {
       /* MESA_FORMAT_B5G6R5_UNORM */
       { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 },
       /* MESA_FORMAT_B8G8R8X8_UNORM */
@@ -202,7 +202,7 @@ driCreateConfigs(mesa_format format,
       { 0x000003FF, 0x000FFC00, 0x3FF00000, 0xC0000000 },
    };
 
-   const uint32_t * masks;
+   const uint64_t * masks;
    __DRIconfig **configs, **c;
    struct gl_config *modes;
    unsigned i, j, k, h;
@@ -414,9 +414,13 @@ static const struct { unsigned int attrib, offset; } attribMap[] = {
     __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE,	transparentBlue),
     __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE,	transparentAlpha),
     __ATTRIB(__DRI_ATTRIB_RED_MASK,			redMask),
+    __ATTRIB(__DRI_ATTRIB_RED_MASK_HI,			redMask),
     __ATTRIB(__DRI_ATTRIB_GREEN_MASK,			greenMask),
+    __ATTRIB(__DRI_ATTRIB_GREEN_MASK_HI,		greenMask),
     __ATTRIB(__DRI_ATTRIB_BLUE_MASK,			blueMask),
+    __ATTRIB(__DRI_ATTRIB_BLUE_MASK_HI,			blueMask),
     __ATTRIB(__DRI_ATTRIB_ALPHA_MASK,			alphaMask),
+    __ATTRIB(__DRI_ATTRIB_ALPHA_MASK_HI,		alphaMask),
     __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH,		maxPbufferWidth),
     __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT,		maxPbufferHeight),
     __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS,		maxPbufferPixels),
@@ -460,6 +464,14 @@ driGetConfigAttribIndex(const __DRIconfig *config,
 	else
 	    *value = 0;
 	break;
+    case __DRI_ATTRIB_RED_MASK_HI:
+    case __DRI_ATTRIB_GREEN_MASK_HI:
+    case __DRI_ATTRIB_BLUE_MASK_HI:
+    case __DRI_ATTRIB_ALPHA_MASK_HI:
+        /* upper 32 bits of 64 bit fields */
+        *value = *(unsigned int *)
+            ((char *) &config->modes + attribMap[index].offset + 4);
+        break;
     default:
         /* any other int-sized field */
 	*value = *(unsigned int *)
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 3d4673a..347a9a9 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -169,7 +169,7 @@ struct gl_config
    GLboolean haveStencilBuffer;
 
    GLint redBits, greenBits, blueBits, alphaBits;	/* bits per comp */
-   GLuint redMask, greenMask, blueMask, alphaMask;
+   GLuint64 redMask, greenMask, blueMask, alphaMask;
    GLint rgbBits;		/* total bits for rgb */
    GLint indexBits;		/* total bits for colorindex */
 
-- 
2.7.4



More information about the mesa-dev mailing list