gallium: add a CAP for mixed colorbuffer format support
authorMarek Olšák <maraeo@gmail.com>
Mon, 28 Mar 2011 00:28:48 +0000 (02:28 +0200)
committerMarek Olšák <maraeo@gmail.com>
Fri, 1 Apr 2011 11:48:01 +0000 (13:48 +0200)
Some GPUs can't do it (I think most of DX9 ones), so they should have
the option not to allow it.

src/gallium/include/pipe/p_defines.h
src/mesa/state_tracker/st_cb_fbo.c

index 4c1879c..431a7fb 100644 (file)
@@ -464,6 +464,7 @@ enum pipe_cap {
    PIPE_CAP_TGSI_INSTANCEID = 43,
    PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR = 44,
    PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL = 45,
+   PIPE_CAP_MIXED_COLORBUFFER_FORMATS = 46,
 };
 
 /* Shader caps not specific to any single stage */
index 0df0428..7ffee90 100644 (file)
@@ -529,6 +529,9 @@ st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
    const struct gl_renderbuffer_attachment *stencil =
          &fb->Attachment[BUFFER_STENCIL];
    GLuint i;
+   enum pipe_format first_format = PIPE_FORMAT_NONE;
+   boolean mixed_formats =
+         screen->get_param(screen, PIPE_CAP_MIXED_COLORBUFFER_FORMATS) != 0;
 
    if (depth->Type && stencil->Type && depth->Type != stencil->Type) {
       fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
@@ -562,13 +565,33 @@ st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
       return;
    }
    for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {
+      struct gl_renderbuffer_attachment *att =
+            &fb->Attachment[BUFFER_COLOR0 + i];
+      enum pipe_format format;
+
       if (!st_validate_attachment(ctx,
                                   screen,
-                                 &fb->Attachment[BUFFER_COLOR0 + i],
+                                 att,
                                  PIPE_BIND_RENDER_TARGET)) {
         fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
         return;
       }
+
+      if (!mixed_formats) {
+         /* Disallow mixed formats. */
+         if (att->Type != GL_NONE) {
+            format = st_renderbuffer(att->Renderbuffer)->surface->format;
+         } else {
+            continue;
+         }
+
+         if (first_format == PIPE_FORMAT_NONE) {
+            first_format = format;
+         } else if (format != first_format) {
+            fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+            return;
+         }
+      }
    }
 }