st/glx: improved depth/stencil format selection code
authorBrian Paul <brianp@vmware.com>
Wed, 24 Feb 2010 01:55:28 +0000 (18:55 -0700)
committerBrian Paul <brianp@vmware.com>
Wed, 24 Feb 2010 01:57:18 +0000 (18:57 -0700)
Actually ask the gallium screen what Z/stencil format is supported.
This will let us remove some hacks in the llvmpipe driver.

src/gallium/state_trackers/glx/xlib/glx_api.c
src/gallium/state_trackers/glx/xlib/xm_api.c
src/gallium/state_trackers/glx/xlib/xm_api.h

index 656a691..08bf624 100644 (file)
@@ -689,6 +689,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
    int desiredVisualID = -1;
    int numAux = 0;
 
+   xmesa_init();
+
    parselist = list;
 
    while (*parselist) {
@@ -941,9 +943,6 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
          /* give the visual some useful GLX attributes */
          double_flag = GL_TRUE;
          rgb_flag = GL_TRUE;
-         depth_size = default_depth_bits();
-         stencil_size = STENCIL_BITS;
-         /* XXX accum??? */
       }
    }
    else if (level==0) {
index 1798faa..188b885 100644 (file)
@@ -319,6 +319,51 @@ choose_pixel_format(XMesaVisual v)
 
 
 
+/**
+ * Query the default gallium screen for a Z/Stencil format that
+ * at least matches the given depthBits and stencilBits.
+ */
+static void
+xmesa_choose_z_stencil_format(int depthBits, int stencilBits,
+                              enum pipe_format *depthFormat,
+                              enum pipe_format *stencilFormat)
+{
+   const enum pipe_texture_target target = PIPE_TEXTURE_2D;
+   const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+   const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE |
+                                PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO);
+   static enum pipe_format formats[] = {
+      PIPE_FORMAT_Z24S8_UNORM,
+      PIPE_FORMAT_S8Z24_UNORM,
+      PIPE_FORMAT_Z16_UNORM,
+      PIPE_FORMAT_Z32_UNORM
+   };
+   int i;
+
+   assert(screen);
+
+   *depthFormat = *stencilFormat = PIPE_FORMAT_NONE;
+
+   /* search for supported format */
+   for (i = 0; i < Elements(formats); i++) {
+      if (screen->is_format_supported(screen, formats[i],
+                                      target, tex_usage, geom_flags)) {
+         *depthFormat = formats[i];
+         break;
+      }
+   }
+
+   if (stencilBits) {
+      *stencilFormat = *depthFormat;
+   }
+
+   /* XXX we should check that he chosen format has at least as many bits
+    * as what was requested.
+    */
+}
+
+
+
 /**********************************************************************/
 /*****                Linked list of XMesaBuffers                 *****/
 /**********************************************************************/
@@ -361,39 +406,9 @@ create_xmesa_buffer(Drawable d, BufferType type,
    /* determine PIPE_FORMATs for buffers */
    colorFormat = choose_pixel_format(vis);
 
-   if (vis->mesa_visual.depthBits == 0)
-      depthFormat = PIPE_FORMAT_NONE;
-#ifdef GALLIUM_CELL /* XXX temporary for Cell! */
-   else
-      depthFormat = PIPE_FORMAT_S8Z24_UNORM;
-#else
-   else if (vis->mesa_visual.depthBits <= 16)
-      depthFormat = PIPE_FORMAT_Z16_UNORM;
-   else if (vis->mesa_visual.depthBits <= 24)
-      depthFormat = PIPE_FORMAT_S8Z24_UNORM;
-   else
-      depthFormat = PIPE_FORMAT_Z32_UNORM;
-#endif
-
-   if (vis->mesa_visual.stencilBits == 8) {
-      if (depthFormat == PIPE_FORMAT_S8Z24_UNORM ||
-          depthFormat == PIPE_FORMAT_Z24S8_UNORM)
-         stencilFormat = depthFormat;
-      else
-         stencilFormat = PIPE_FORMAT_S8_UNORM;
-   }
-   else {
-      /* no stencil */
-      stencilFormat = PIPE_FORMAT_NONE;
-      if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) {
-         /* use 24-bit Z, undefined stencil channel */
-         depthFormat = PIPE_FORMAT_X8Z24_UNORM;
-      }
-      else if (depthFormat == PIPE_FORMAT_Z24S8_UNORM) {
-         /* use 24-bit Z, undefined stencil channel */
-         depthFormat = PIPE_FORMAT_Z24X8_UNORM;
-      }
-   }
+   xmesa_choose_z_stencil_format(vis->mesa_visual.depthBits,
+                                 vis->mesa_visual.stencilBits,
+                                 &depthFormat, &stencilFormat);
 
 
    get_drawable_size(vis->display, d, &width, &height);
@@ -658,6 +673,8 @@ XMesaVisual XMesaCreateVisual( Display *display,
    XMesaVisual v;
    GLint red_bits, green_bits, blue_bits, alpha_bits;
 
+   xmesa_init();
+
    /* For debugging only */
    if (_mesa_getenv("MESA_XSYNC")) {
       /* This makes debugging X easier.
@@ -753,6 +770,21 @@ void XMesaDestroyVisual( XMesaVisual v )
 }
 
 
+/**
+ * Do one-time initializations.
+ */
+void
+xmesa_init(void)
+{
+   static GLboolean firstTime = GL_TRUE;
+   if (firstTime) {
+      pipe_mutex_init(_xmesa_lock);
+      _screen = driver.create_pipe_screen();
+      screen = trace_screen_create( _screen );
+      firstTime = GL_FALSE;
+   }
+}
+
 
 /**
  * Create a new XMesaContext.
@@ -764,18 +796,12 @@ void XMesaDestroyVisual( XMesaVisual v )
 PUBLIC
 XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
 {
-   static GLboolean firstTime = GL_TRUE;
    struct pipe_context *pipe = NULL;
    XMesaContext c;
    GLcontext *mesaCtx;
    uint pf;
 
-   if (firstTime) {
-      pipe_mutex_init(_xmesa_lock);
-      _screen = driver.create_pipe_screen();
-      screen = trace_screen_create( _screen );
-      firstTime = GL_FALSE;
-   }
+   xmesa_init();
 
    /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
    c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
index 63a329c..004cb26 100644 (file)
@@ -367,6 +367,9 @@ xmesa_buffer(GLframebuffer *fb)
 
 
 extern void
+xmesa_init(void);
+
+extern void
 xmesa_delete_framebuffer(struct gl_framebuffer *fb);
 
 extern XMesaBuffer