clean-up/re-org of intel_framebuffer code
[mesa.git] / src / mesa / drivers / x11 / xm_surface.c
index 8d2c2ca5f38b94630b7d52507fa36fe407a3fcdd..5533158ece00b8904b48939e617a5bdfe2e26230 100644 (file)
@@ -27,7 +27,7 @@
  * \file xm_surface.c
  * Code to allow the softpipe code to write to X windows/buffers.
  * This is a bit of a hack for now.  We've basically got two different
- * abstractions for color buffers: gl_renderbuffer and softpipe_surface.
+ * abstractions for color buffers: gl_renderbuffer and pipe_surface.
  * They'll need to get merged someday...
  * For now, they're separate things that point to each other.
  */
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
+#include "pipe/p_winsys.h"
 #include "pipe/softpipe/sp_context.h"
 #include "pipe/softpipe/sp_clear.h"
+#include "pipe/softpipe/sp_tile_cache.h"
+#include "pipe/softpipe/sp_surface.h"
 #include "state_tracker/st_context.h"
 
 
 
 
 static INLINE struct xmesa_surface *
-xmesa_surf(struct softpipe_surface *sps)
+xmesa_surface(struct pipe_surface *ps)
 {
-   return (struct xmesa_surface *) sps;
+   return (struct xmesa_surface *) ps;
 }
 
 
 static INLINE struct xmesa_renderbuffer *
-xmesa_rb(struct softpipe_surface *sps)
+xmesa_rb(struct pipe_surface *ps)
 {
-   struct xmesa_surface *xms = xmesa_surf(sps);
+   struct xmesa_surface *xms = xmesa_surface(ps);
    return xms->xrb;
 }
 
@@ -76,148 +79,70 @@ xmesa_rb(struct softpipe_surface *sps)
 #define FLIP(Y) Y = xrb->St.Base.Height - (Y) - 1;
 
 
-/**
- * quad reading/writing
- * These functions are just wrappers around the existing renderbuffer
- * functions.
- * Note that Y=0 is the top of the surface.
- */
-
-static void
-read_quad_f(struct softpipe_surface *sps, GLint x, GLint y,
-            GLfloat (*rgba)[NUM_CHANNELS])
-{
-   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
-   GLubyte temp[16];
-   GLfloat *dst = (GLfloat *) rgba;
-   GLuint i;
-   GET_CURRENT_CONTEXT(ctx);
-   FLIP(y);
-   xrb->St.Base.GetRow(ctx, &xrb->St.Base, 2, x, y,     temp);
-   xrb->St.Base.GetRow(ctx, &xrb->St.Base, 2, x, y - 1, temp + 8);
-   for (i = 0; i < 16; i++) {
-      dst[i] = UBYTE_TO_FLOAT(temp[i]);
-   }
-}
-
-static void
-read_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y,
-                GLfloat (*rrrr)[QUAD_SIZE])
+void
+xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
+                    uint x, uint y, uint w, uint h, float *p)
 {
-   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
-   GLubyte temp[16];
-   GLfloat *dst = (GLfloat *) rrrr;
-   GLuint i, j;
-   GET_CURRENT_CONTEXT(ctx);
-   FLIP(y);
-   xrb->St.Base.GetRow(ctx, &xrb->St.Base, 2, x, y,     temp);
-   xrb->St.Base.GetRow(ctx, &xrb->St.Base, 2, x, y - 1, temp + 8);
-   for (i = 0; i < 4; i++) {
-      for (j = 0; j < 4; j++) {
-         dst[j * 4 + i] = UBYTE_TO_FLOAT(temp[i * 4 + j]);
-      }
-   }
-}
+   struct xmesa_surface *xms = xmesa_surface(ps);
+   struct xmesa_renderbuffer *xrb = xms->xrb;
+
+   if (xrb) {
+      /* this is a front/back color buffer */
+      GLubyte tmp[MAX_WIDTH * 4];
+      GLuint i, j;
+      uint w0 = w;
+      GET_CURRENT_CONTEXT(ctx);
 
-static void
-write_quad_f(struct softpipe_surface *sps, GLint x, GLint y,
-             GLfloat (*rgba)[NUM_CHANNELS])
-{
-   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
-   GLubyte temp[16];
-   const GLfloat *src = (const GLfloat *) rgba;
-   GLuint i;
-   GET_CURRENT_CONTEXT(ctx);
-   FLIP(y);
-   for (i = 0; i < 16; i++) {
-      UNCLAMPED_FLOAT_TO_UBYTE(temp[i], src[i]);
-   }
-   xrb->St.Base.PutRow(ctx, &xrb->St.Base, 2, x, y,     temp,     NULL);
-   xrb->St.Base.PutRow(ctx, &xrb->St.Base, 2, x, y - 1, temp + 8, NULL);
-}
+      CLIP_TILE;
 
-static void
-write_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y,
-                 GLfloat (*rrrr)[QUAD_SIZE])
-{
-   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
-   GLubyte temp[16];
-   const GLfloat *src = (const GLfloat *) rrrr;
-   GLuint i, j;
-   GET_CURRENT_CONTEXT(ctx);
-   FLIP(y);
-   for (i = 0; i < 4; i++) {
-      for (j = 0; j < 4; j++) {
-         UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + i], src[i * 4 + j]);
+      FLIP(y);
+      for (i = 0; i < h; i++) {
+         xrb->St.Base.GetRow(ctx, &xrb->St.Base, w, x, y - i, tmp);
+         for (j = 0; j < w * 4; j++) {
+            p[j] = UBYTE_TO_FLOAT(tmp[j]);
+         }
+         p += w0 * 4;
       }
    }
-   xrb->St.Base.PutRow(ctx, &xrb->St.Base, 2, x, y,     temp,     NULL);
-   xrb->St.Base.PutRow(ctx, &xrb->St.Base, 2, x, y - 1, temp + 8, NULL);
-}
-
-static void
-read_quad_ub(struct softpipe_surface *sps, GLint x, GLint y,
-             GLubyte (*rgba)[NUM_CHANNELS])
-{
-   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
-   GET_CURRENT_CONTEXT(ctx);
-   FLIP(y);
-   xrb->St.Base.GetRow(ctx, &xrb->St.Base, 2, x, y,     rgba);
-   xrb->St.Base.GetRow(ctx, &xrb->St.Base, 2, x, y - 1, rgba + 2);
-}
-
-static void
-write_quad_ub(struct softpipe_surface *sps, GLint x, GLint y,
-              GLubyte (*rgba)[NUM_CHANNELS])
-{
-   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
-   GET_CURRENT_CONTEXT(ctx);
-   FLIP(y);
-   xrb->St.Base.GetRow(ctx, &xrb->St.Base, 2, x, y,     rgba);
-   xrb->St.Base.GetRow(ctx, &xrb->St.Base, 2, x, y - 1, rgba + 2);
-}
-
-
-static void
-get_tile(struct pipe_surface *ps,
-         GLuint x, GLuint y, GLuint w, GLuint h, GLfloat *p)
-{
-   struct xmesa_renderbuffer *xrb = xmesa_rb((struct softpipe_surface *) ps);
-   GLubyte tmp[MAX_WIDTH * 4];
-   GLuint i, j;
-   unsigned w0 = w;
-   GET_CURRENT_CONTEXT(ctx);
-
-   CLIP_TILE;
-
-   FLIP(y);
-   for (i = 0; i < h; i++) {
-      xrb->St.Base.GetRow(ctx, &xrb->St.Base, w, x, y - i, tmp);
-      for (j = 0; j < w * 4; j++) {
-         p[j] = UBYTE_TO_FLOAT(tmp[j]);
-      }
-      p += w0 * 4;
+   else {
+      /* other softpipe surface */
+      softpipe_get_tile_rgba(pipe, ps, x, y, w, h, p);
    }
 }
 
 
-static void
-put_tile(struct pipe_surface *ps,
-         GLuint x, GLuint y, GLuint w, GLuint h, const GLfloat *p)
+void
+xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
+                    uint x, uint y, uint w, uint h, const float *p)
 {
-   struct xmesa_renderbuffer *xrb = xmesa_rb((struct softpipe_surface *) ps);
-   GLubyte tmp[MAX_WIDTH * 4];
-   GLuint i, j;
-   unsigned w0 = w;
-   GET_CURRENT_CONTEXT(ctx);
-   CLIP_TILE;
-   FLIP(y);
-   for (i = 0; i < h; i++) {
-      for (j = 0; j < w * 4; j++) {
-         UNCLAMPED_FLOAT_TO_UBYTE(tmp[j], p[j]);
+   struct xmesa_surface *xms = xmesa_surface(ps);
+   struct xmesa_renderbuffer *xrb = xms->xrb;
+
+   if (xrb) {
+      /* this is a front/back color buffer */
+      GLubyte tmp[MAX_WIDTH * 4];
+      GLuint i, j;
+      uint w0 = w;
+      GET_CURRENT_CONTEXT(ctx);
+      CLIP_TILE;
+      FLIP(y);
+      for (i = 0; i < h; i++) {
+         for (j = 0; j < w * 4; j++) {
+            UNCLAMPED_FLOAT_TO_UBYTE(tmp[j], p[j]);
+         }
+         xrb->St.Base.PutRow(ctx, &xrb->St.Base, w, x, y - i, tmp, NULL);
+         p += w0 * 4;
       }
-      xrb->St.Base.PutRow(ctx, &xrb->St.Base, w, x, y - i, tmp, NULL);
-      p += w0 * 4;
+#if 0 /* debug: flush */
+      {
+         XMesaContext xm = XMESA_CONTEXT(ctx);
+         XSync(xm->display, 0);
+      }
+#endif
+   }
+   else {
+      /* other softpipe surface */
+      softpipe_put_tile_rgba(pipe, ps, x, y, w, h, p);
    }
 }
 
@@ -235,33 +160,8 @@ xmesa_new_color_surface(struct pipe_context *pipe, GLuint pipeFormat)
 
    assert(pipeFormat);
 
-   xms->surface.surface.format = pipeFormat;
-   xms->surface.surface.refcount = 1;
-
-   /* some of the functions plugged in by this call will get overridden */
-   softpipe_init_surface_funcs(&xms->surface);
-
-   switch (pipeFormat) {
-   case PIPE_FORMAT_U_A8_R8_G8_B8:
-      xms->surface.read_quad_f_swz = read_quad_f;
-      xms->surface.read_quad_f = read_quad_f;
-      xms->surface.read_quad_f_swz = read_quad_f_swz;
-      xms->surface.read_quad_ub = read_quad_ub;
-      xms->surface.write_quad_f = write_quad_f;
-      xms->surface.write_quad_f_swz = write_quad_f_swz;
-      xms->surface.write_quad_ub = write_quad_ub;
-      xms->surface.surface.get_tile = get_tile;
-      xms->surface.surface.put_tile = put_tile;
-      break;
-   case PIPE_FORMAT_S8_Z24:
-      /*
-      xms->surface.read_quad_z = 1;
-      xms->surface.write_quad_z = 1;
-      */
-      break;
-   default:
-      abort();
-   }
+   xms->surface.format = pipeFormat;
+   xms->surface.refcount = 1;
 
    /* Note, the region we allocate doesn't actually have any storage
     * since we're drawing into an XImage or Pixmap.
@@ -269,9 +169,10 @@ xmesa_new_color_surface(struct pipe_context *pipe, GLuint pipeFormat)
     * functions.
     */
    if (pipe)
-      xms->surface.surface.region = pipe->region_alloc(pipe, 1, 0, 0, 0x0);
+      xms->surface.region = pipe->winsys->region_alloc(pipe->winsys,
+                                                       1, 0, 0, 0x0);
 
-   return &xms->surface.surface;
+   return &xms->surface;
 }
 
 
@@ -287,29 +188,23 @@ xmesa_surface_alloc(struct pipe_context *pipe, GLuint pipeFormat)
    assert(pipe);
    assert(pipeFormat);
 
-   xms->surface.surface.format = pipeFormat;
-   xms->surface.surface.refcount = 1;
-   /*
-    * This is really just a softpipe surface, not an XImage/Pixmap surface.
-    */
-   softpipe_init_surface_funcs(&xms->surface);
+   xms->surface.format = pipeFormat;
+   xms->surface.refcount = 1;
 
-   return &xms->surface.surface;
+   return &xms->surface;
 }
 
 
-const GLuint *
-xmesa_supported_formats(struct pipe_context *pipe, GLuint *numFormats)
+boolean
+xmesa_is_format_supported(struct pipe_context *pipe, uint format)
 {
-   static const GLuint formats[] = {
-      PIPE_FORMAT_U_A8_R8_G8_B8,
-      PIPE_FORMAT_S_R16_G16_B16_A16,
-      PIPE_FORMAT_S8_Z24
+   switch( format ) {
+   case PIPE_FORMAT_U_A8_R8_G8_B8:
+   case PIPE_FORMAT_S_R16_G16_B16_A16:
+   case PIPE_FORMAT_S8_Z24:
+      return TRUE;
    };
-
-   *numFormats = sizeof(formats) / sizeof(formats[0]);
-
-   return formats;
+   return FALSE;
 }
 
 
@@ -319,7 +214,24 @@ xmesa_supported_formats(struct pipe_context *pipe, GLuint *numFormats)
 void
 xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, GLuint value)
 {
-   struct xmesa_renderbuffer *xrb = xmesa_rb((struct softpipe_surface *) ps);
+   struct xmesa_renderbuffer *xrb = xmesa_rb(ps);
+
+   /* XXX actually, we should just discard any cached tiles from this
+    * surface since we don't want to accidentally re-use them after clearing.
+    */
+   pipe->flush(pipe, 0);
+
+   {
+      struct softpipe_context *sp = softpipe_context(pipe);
+      if (ps == sp_tile_cache_get_surface(sp->cbuf_cache[0])) {
+         float clear[4];
+         clear[0] = 0.2; /* XXX hack */
+         clear[1] = 0.2;
+         clear[2] = 0.2;
+         clear[3] = 0.2;
+         sp_tile_cache_clear(sp->cbuf_cache[0], clear);
+      }
+   }
 
    if (xrb && xrb->ximage) {
       /* clearing back color buffer */