gallium dri st: Probe the driver for supported surface formats.
authorThomas Hellstrom <thellstrom@vmware.com>
Tue, 16 Jun 2009 23:08:25 +0000 (01:08 +0200)
committerThomas Hellstrom <thellstrom@vmware.com>
Wed, 17 Jun 2009 01:07:01 +0000 (03:07 +0200)
This is done when constructing the fbconfigs, and the result is saved
for window system framebuffer creation.

Note: For dri2 the server needs to have an identical format selection
logic. Otherwise the dri state-tracker and the xorg driver (state-tracker)
will disagree on which format to use for the attachments. Some more work
is needed in this area.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
src/gallium/state_trackers/dri/dri_drawable.c
src/gallium/state_trackers/dri/dri_drawable.h
src/gallium/state_trackers/dri/dri_screen.c
src/gallium/state_trackers/dri/dri_screen.h

index 09cd3091d220bc4d372941a46f29d0abf4e8f475..815055b15b9bb8e00fc3ca5b00a55136e36d2d8d 100644 (file)
@@ -157,29 +157,28 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
       switch (buffers[i].attachment) {
       case __DRI_BUFFER_FRONT_LEFT:
         index = ST_SURFACE_FRONT_LEFT;
-        format = PIPE_FORMAT_A8R8G8B8_UNORM;
+        format = drawable->color_format;
         break;
       case __DRI_BUFFER_FAKE_FRONT_LEFT:
         index = ST_SURFACE_FRONT_LEFT;
-        format = PIPE_FORMAT_A8R8G8B8_UNORM;
+        format = drawable->color_format;
         break;
       case __DRI_BUFFER_BACK_LEFT:
         index = ST_SURFACE_BACK_LEFT;
-        format = PIPE_FORMAT_A8R8G8B8_UNORM;
+        format = drawable->color_format;
         break;
       case __DRI_BUFFER_DEPTH:
         index = ST_SURFACE_DEPTH;
-        format = PIPE_FORMAT_Z24S8_UNORM;
+        format = drawable->depth_format;
         break;
       case __DRI_BUFFER_STENCIL:
         index = ST_SURFACE_DEPTH;
-        format = PIPE_FORMAT_Z24S8_UNORM;
+        format = drawable->stencil_format;
         break;
       case __DRI_BUFFER_ACCUM:
       default:
         assert(0);
       }
-      assert(buffers[i].cpp == 4);
 
       if (index == ST_SURFACE_DEPTH) {
         if (have_depth)
@@ -218,10 +217,8 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
                  __DRIdrawablePrivate * dPriv,
                  const __GLcontextModes * visual, boolean isPixmap)
 {
-   enum pipe_format colorFormat, depthFormat, stencilFormat;
    struct dri_screen *screen = sPriv->private;
    struct dri_drawable *drawable = NULL;
-   struct pipe_screen *pscreen = screen->pipe_screen;
    int i;
 
    if (isPixmap)
@@ -231,39 +228,52 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
    if (drawable == NULL)
       goto fail;
 
-   /* XXX: todo: use the pipe_screen queries to figure out which
-    * render targets are supportable.
-    */
-   assert(visual->redBits == 8);
-   assert(visual->depthBits == 24 || visual->depthBits == 0);
-   assert(visual->stencilBits == 8 || visual->stencilBits == 0);
-
-   colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
+   drawable->color_format = (visual->redBits == 8) ?
+      PIPE_FORMAT_A8R8G8B8_UNORM : PIPE_FORMAT_R5G6B5_UNORM;
+
+   debug_printf("Red bits is %d\n", visual->redBits);
+
+   switch(visual->depthBits) {
+   default:
+   case 0:
+      debug_printf("Depth buffer 0.\n");
+      drawable->depth_format = PIPE_FORMAT_NONE;
+      break;
+   case 16:
+      debug_printf("Depth buffer 16.\n");
+      drawable->depth_format = PIPE_FORMAT_Z16_UNORM;
+      break;
+   case 24:
+      if (visual->stencilBits == 0) {
+         debug_printf("Depth buffer 24. Stencil 0.\n");
+        drawable->depth_format = (screen->d_depth_bits_last) ?
+           PIPE_FORMAT_X8Z24_UNORM:
+           PIPE_FORMAT_Z24X8_UNORM;
+      } else {
+         debug_printf("Combined depth stencil 24 / 8.\n");
+        drawable->depth_format = (screen->sd_depth_bits_last) ?
+           PIPE_FORMAT_S8Z24_UNORM:
+           PIPE_FORMAT_Z24S8_UNORM;
+      }
+      break;
+   }
 
-   if (visual->depthBits) {
-      if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM,
-                                      PIPE_TEXTURE_2D,
-                                      PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0))
-        depthFormat = PIPE_FORMAT_Z24S8_UNORM;
-      else
-        depthFormat = PIPE_FORMAT_S8Z24_UNORM;
-   } else
-      depthFormat = PIPE_FORMAT_NONE;
-
-   if (visual->stencilBits) {
-      if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM,
-                                      PIPE_TEXTURE_2D,
-                                      PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0))
-        stencilFormat = PIPE_FORMAT_Z24S8_UNORM;
-      else
-        stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
-   } else
-      stencilFormat = PIPE_FORMAT_NONE;
+   switch(visual->stencilBits) {
+   default:
+   case 0:
+      drawable->stencil_format = PIPE_FORMAT_NONE;
+      break;
+   case 8:
+      drawable->stencil_format = (screen->sd_depth_bits_last) ?
+        PIPE_FORMAT_S8Z24_UNORM:
+         PIPE_FORMAT_Z24S8_UNORM;
+      break;
+   }
 
    drawable->stfb = st_create_framebuffer(visual,
-                                         colorFormat,
-                                         depthFormat,
-                                         stencilFormat,
+                                         drawable->color_format,
+                                         drawable->depth_format,
+                                         drawable->stencil_format,
                                          dPriv->w,
                                          dPriv->h, (void *)drawable);
    if (drawable->stfb == NULL)
index 0f654d804a7dceb4582c757bd636a2e2df647aee..2fbd5f1eb7cc6dc0774fed6f3aedabdd6ad10f11 100644 (file)
@@ -58,6 +58,10 @@ struct dri_drawable
    unsigned int tail;
    unsigned int desired_fences;
    unsigned int cur_fences;
+
+   enum pipe_format color_format;
+   enum pipe_format depth_format;
+   enum pipe_format stencil_format;
 };
 
 static INLINE struct dri_drawable *
index d3392ee690ba65bb8dad1d853ea83979e936f18c..c36bfe30ff81440fead92d0fb4fc509ff91e28ff 100644 (file)
@@ -69,39 +69,65 @@ PUBLIC const char __driConfigOptions[] =
 struct dri1_api *__dri1_api_hooks = NULL;
 
 static const __DRIconfig **
-dri_fill_in_modes(__DRIscreenPrivate * psp,
-                 unsigned pixel_bits, unsigned depth_bits,
-                 unsigned stencil_bits, GLboolean have_back_buffer)
+dri_fill_in_modes(struct dri_screen *screen,
+                 unsigned pixel_bits)
 {
    __DRIconfig **configs;
-   __GLcontextModes *m;
    unsigned num_modes;
-   uint8_t depth_bits_array[3];
-   uint8_t stencil_bits_array[3];
+   uint8_t depth_bits_array[4];
+   uint8_t stencil_bits_array[4];
    uint8_t msaa_samples_array[1];
    unsigned depth_buffer_factor;
    unsigned back_buffer_factor;
    unsigned msaa_samples_factor;
    GLenum fb_format;
    GLenum fb_type;
-   int i;
+   struct pipe_screen *p_screen = screen->pipe_screen;
 
    static const GLenum back_buffer_modes[] = {
       GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
    };
 
-   /* TODO probe the hardware of what is supports */
    depth_bits_array[0] = 0;
-   depth_bits_array[1] = 24;
-   depth_bits_array[2] = 24;
-
-   stencil_bits_array[0] = 0;         /* no depth or stencil */
-   stencil_bits_array[1] = 0;         /* z24x8 */
-   stencil_bits_array[2] = 8;         /* z24s8 */
+   stencil_bits_array[0] = 0;
+   depth_buffer_factor = 1;
+
+   if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
+                                    PIPE_TEXTURE_2D,
+                                    PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) {
+      depth_bits_array[depth_buffer_factor] = 16;
+      stencil_bits_array[depth_buffer_factor++] = 0;
+   }
+   if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
+                                    PIPE_TEXTURE_2D,
+                                    PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) {
+      depth_bits_array[depth_buffer_factor] = 24;
+      stencil_bits_array[depth_buffer_factor++] = 0;
+      screen->d_depth_bits_last = TRUE;
+   } else if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
+                                           PIPE_TEXTURE_2D,
+                                           PIPE_TEXTURE_USAGE_DEPTH_STENCIL,
+                                           0)) {
+      depth_bits_array[depth_buffer_factor] = 24;
+      stencil_bits_array[depth_buffer_factor++] = 0;
+      screen->d_depth_bits_last = FALSE;
+   }
+   if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
+                                    PIPE_TEXTURE_2D,
+                                    PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) {
+      depth_bits_array[depth_buffer_factor] = 24;
+      stencil_bits_array[depth_buffer_factor++] = 8;
+      screen->sd_depth_bits_last = FALSE;
+   } else if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
+                                           PIPE_TEXTURE_2D,
+                                           PIPE_TEXTURE_USAGE_DEPTH_STENCIL,
+                                           0)) {
+      depth_bits_array[depth_buffer_factor] = 24;
+      stencil_bits_array[depth_buffer_factor++] = 8;
+      screen->sd_depth_bits_last = TRUE;
+   }
 
    msaa_samples_array[0] = 0;
-
-   depth_buffer_factor = 3;
    back_buffer_factor = 3;
    msaa_samples_factor = 1;
 
@@ -109,9 +135,19 @@ dri_fill_in_modes(__DRIscreenPrivate * psp,
       depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
 
    if (pixel_bits == 16) {
+      if (!p_screen->is_format_supported(p_screen,
+                                        PIPE_FORMAT_R5G6B5_UNORM,
+                                        PIPE_TEXTURE_2D,
+                                        PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+        return NULL;
       fb_format = GL_RGB;
       fb_type = GL_UNSIGNED_SHORT_5_6_5;
    } else {
+      if (!p_screen->is_format_supported(p_screen,
+                                        PIPE_FORMAT_A8R8G8B8_UNORM,
+                                        PIPE_TEXTURE_2D,
+                                        PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+        return NULL;
       fb_format = GL_BGRA;
       fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
    }
@@ -126,13 +162,6 @@ dri_fill_in_modes(__DRIscreenPrivate * psp,
       return NULL;
    }
 
-   for (i = 0; configs[i]; i++) {
-      m = &configs[i]->modes;
-      if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
-        m->visualRating = GLX_SLOW_CONFIG;
-      }
-   }
-
    return (const const __DRIconfig **)configs;
 }
 
@@ -200,7 +229,13 @@ dri_init_screen(__DRIscreenPrivate * sPriv)
    driParseOptionInfo(&screen->optionCache,
                      __driConfigOptions, __driNConfigOptions);
 
-   configs = dri_fill_in_modes(sPriv, sPriv->fbBPP, 24, 8, 1);
+   /**
+    * FIXME: If the driver supports format conversion swapbuffer blits, we might
+    * want to support other color bit depths than the server is currently
+    * using.
+    */
+
+   configs = dri_fill_in_modes(screen, sPriv->fbBPP);
    if (!configs)
       goto out_no_configs;
 
@@ -248,7 +283,7 @@ dri_init_screen2(__DRIscreenPrivate * sPriv)
    driParseOptionInfo(&screen->optionCache,
                      __driConfigOptions, __driNConfigOptions);
 
-   return dri_fill_in_modes(sPriv, 4 * 8, 24, 8, 1);
+   return dri_fill_in_modes(screen, 32);
  fail:
    return NULL;
 }
index 100d9e50e075a62d294685047c86cad2f7d7fab4..090f9fee7c57b9a9c0809e355d69455313a2a0de 100644 (file)
@@ -62,6 +62,8 @@ struct dri_screen
    /* gallium */
    struct pipe_winsys *pipe_winsys;
    struct pipe_screen *pipe_screen;
+   boolean d_depth_bits_last;
+   boolean sd_depth_bits_last;
 };
 
 /** cast wrapper */