gallium: fix surface/texture format conversion in st_CopyPixels
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 28 Feb 2008 18:31:56 +0000 (11:31 -0700)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 28 Feb 2008 18:36:54 +0000 (11:36 -0700)
If the src buffer's format isn't supported as a texture format, find a different
texture format.

src/mesa/state_tracker/st_cb_drawpixels.c

index e0dc657b4577296200d6060da4d713163bcf44c2..6c0d75cc550214c13c206f30abd58ffef61869b4 100644 (file)
@@ -1216,7 +1216,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    struct pipe_surface *psTex;
    struct pipe_texture *pt;
    GLfloat *color;
-   enum pipe_format format;
+   enum pipe_format srcFormat, texFormat;
 
    /* make sure rendering has completed */
    pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
@@ -1236,6 +1236,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
       stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE);
    }
    else {
+      assert(type == GL_DEPTH);
       rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
       color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
       stfp = make_fragment_shader_z(ctx->st);
@@ -1243,10 +1244,39 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    psRead = rbRead->surface;
-   format = psRead->format;
+   srcFormat = psRead->format;
 
-   pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, width, height,
-                         1, 0);
+   if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE)) {
+      texFormat = srcFormat;
+   }
+   else {
+      /* srcFormat can't be used as a texture format */
+      if (type == GL_DEPTH) {
+         static const enum pipe_format zFormats[] = {
+            PIPE_FORMAT_Z16_UNORM,
+            PIPE_FORMAT_Z32_UNORM,
+            PIPE_FORMAT_S8Z24_UNORM,
+            PIPE_FORMAT_Z24S8_UNORM
+         };
+         uint i;
+         texFormat = 0;
+         for (i = 0; i < Elements(zFormats); i++) {
+            if (screen->is_format_supported(screen, zFormats[i],
+                                            PIPE_TEXTURE)) {
+               texFormat = zFormats[i];
+               break;
+            }
+         }
+         assert(texFormat); /* XXX no depth texture formats??? */
+      }
+      else {
+         /* todo */
+         assert(0);
+      }
+   }
+
+   pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
+                          width, height, 1, 0);
    if (!pt)
       return;
 
@@ -1260,7 +1290,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
     * front/back color buffers as surfaces (they're XImages and Pixmaps).
     * So, this var tells us if we can use surface_copy here...
     */
-   if (st->haveFramebufferSurfaces) {
+   if (st->haveFramebufferSurfaces && srcFormat == texFormat) {
       /* copy source framebuffer surface into mipmap/texture */
       pipe->surface_copy(pipe,
                          FALSE,