Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / mesa / state_tracker / st_cb_drawpixels.c
index 33d34445ee0f975c9caa2e1fd85200d0b5cf64e0..5b24b9f06874cf0c6eaeb63213f7511bf30f8bde 100644 (file)
 
 #include "main/imports.h"
 #include "main/image.h"
+#include "main/bufferobj.h"
 #include "main/macros.h"
 #include "main/texformat.h"
+#include "main/state.h"
 #include "shader/program.h"
 #include "shader/prog_parameter.h"
 #include "shader/prog_print.h"
@@ -54,8 +56,8 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
-#include "pipe/p_winsys.h"
-#include "util/p_tile.h"
+#include "util/u_tile.h"
+#include "util/u_draw_quad.h"
 #include "shader/prog_instruction.h"
 #include "cso_cache/cso_context.h"
 
@@ -85,140 +87,6 @@ is_passthrough_program(const struct gl_fragment_program *prog)
 }
 
 
-/**
- * Make fragment program for glBitmap:
- *   Sample the texture and kill the fragment if the bit is 0.
- * This program will be combined with the user's fragment program.
- */
-static struct st_fragment_program *
-make_bitmap_fragment_program(GLcontext *ctx)
-{
-   struct st_fragment_program *stfp;
-   struct gl_program *p;
-   GLuint ic = 0;
-
-   p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
-   if (!p)
-      return NULL;
-
-   p->NumInstructions = 5;
-
-   p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
-   if (!p->Instructions) {
-      ctx->Driver.DeleteProgram(ctx, p);
-      return NULL;
-   }
-   _mesa_init_instructions(p->Instructions, p->NumInstructions);
-
-   /* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */
-   p->Instructions[ic].Opcode = OPCODE_TEX;
-   p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
-   p->Instructions[ic].DstReg.Index = 0;
-   p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
-   p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
-   p->Instructions[ic].TexSrcUnit = 0;
-   p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
-   ic++;
-
-   /* SWZ tmp0.x, tmp0.x, 1111; # tmp0.x = 1.0 */
-   p->Instructions[ic].Opcode = OPCODE_SWZ;
-   p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
-   p->Instructions[ic].DstReg.Index = 0;
-   p->Instructions[ic].DstReg.WriteMask = WRITEMASK_X;
-   p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
-   p->Instructions[ic].SrcReg[0].Index = 0;
-   p->Instructions[ic].SrcReg[0].Swizzle
-      = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE );
-   ic++;
-
-   /* SUB tmp0, tmp0.wwww, tmp0.xxxx;  #  tmp0.w -= 1 */
-   p->Instructions[ic].Opcode = OPCODE_SUB;
-   p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
-   p->Instructions[ic].DstReg.Index = 0;
-   p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
-   p->Instructions[ic].SrcReg[0].Index = 0;
-   p->Instructions[ic].SrcReg[0].Swizzle = SWIZZLE_WWWW;
-   p->Instructions[ic].SrcReg[1].File = PROGRAM_TEMPORARY;
-   p->Instructions[ic].SrcReg[1].Index = 0;
-   p->Instructions[ic].SrcReg[1].Swizzle = SWIZZLE_XXXX; /* 1.0 */
-   ic++;
-
-   /* KIL if tmp0 < 0 */
-   p->Instructions[ic].Opcode = OPCODE_KIL;
-   p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
-   p->Instructions[ic].SrcReg[0].Index = 0;
-   ic++;
-
-   /* END; */
-   p->Instructions[ic++].Opcode = OPCODE_END;
-
-   assert(ic == p->NumInstructions);
-
-   p->InputsRead = FRAG_BIT_TEX0;
-   p->OutputsWritten = 0x0;
-
-   stfp = (struct st_fragment_program *) p;
-   stfp->Base.UsesKill = GL_TRUE;
-   st_translate_fragment_program(ctx->st, stfp, NULL);
-
-   return stfp;
-}
-
-
-/**
- * Combine basic bitmap fragment program with the user-defined program.
- */
-static struct st_fragment_program *
-combined_bitmap_fragment_program(GLcontext *ctx)
-{
-   struct st_context *st = ctx->st;
-   struct st_fragment_program *stfp;
-
-   if (!st->bitmap.program) {
-      /* create the basic bitmap fragment program */
-      st->bitmap.program = make_bitmap_fragment_program(ctx);
-   }
-
-   if (st->bitmap.user_prog_sn == st->fp->serialNo) {
-      /* re-use */
-      stfp = st->bitmap.combined_prog;
-   }
-   else {
-      /* Concatenate the bitmap program with the current user-defined program.
-       */
-      stfp = (struct st_fragment_program *)
-         _mesa_combine_programs(ctx,
-                                &st->bitmap.program->Base.Base,
-                                &st->fp->Base.Base);
-
-#if 0
-      {
-         struct gl_program *p = &stfp->Base.Base;
-         printf("Combined bitmap program:\n");
-         _mesa_print_program(p);
-         printf("InputsRead: 0x%x\n", p->InputsRead);
-         printf("OutputsWritten: 0x%x\n", p->OutputsWritten);
-         _mesa_print_parameter_list(p->Parameters);
-      }
-#endif
-
-      /* translate to TGSI tokens */
-      st_translate_fragment_program(st, stfp, NULL);
-
-      /* save new program, update serial numbers */
-      st->bitmap.user_prog_sn = st->fp->serialNo;
-      st->bitmap.combined_prog = stfp;
-   }
-
-   /* Ideally we'd have updated the pipe constants during the normal
-    * st/atom mechanism.  But we can't since this is specific to glBitmap.
-    */
-   st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
-
-   return stfp;
-}
-
-
 
 /**
  * Make fragment shader for glDraw/CopyPixels.  This shader is made
@@ -246,6 +114,12 @@ combined_drawpix_fragment_program(GLcontext *ctx)
             _mesa_clone_program(ctx, &st->pixel_xfer.program->Base.Base);
       }
       else {
+#if 0
+         printf("Base program:\n");
+         _mesa_print_program(&st->fp->Base.Base);
+         printf("DrawPix program:\n");
+         _mesa_print_program(&st->pixel_xfer.program->Base.Base);
+#endif
          stfp = (struct st_fragment_program *)
             _mesa_combine_programs(ctx,
                                    &st->pixel_xfer.program->Base.Base,
@@ -291,14 +165,16 @@ static struct st_fragment_program *
 make_fragment_shader_z(struct st_context *st)
 {
    GLcontext *ctx = st->ctx;
-   /* only make programs once and re-use */
-   static struct st_fragment_program *stfp = NULL;
    struct gl_program *p;
    GLuint ic = 0;
 
-   if (stfp)
-      return stfp;
+   if (st->drawpix.z_shader) {
+      return st->drawpix.z_shader;
+   }
 
+   /*
+    * Create shader now
+    */
    p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
    if (!p)
       return NULL;
@@ -338,11 +214,12 @@ make_fragment_shader_z(struct st_context *st)
 
    p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0;
    p->OutputsWritten = (1 << FRAG_RESULT_COLR) | (1 << FRAG_RESULT_DEPR);
+   p->SamplersUsed = 0x1;  /* sampler 0 (bit 0) is used */
 
-   stfp = (struct st_fragment_program *) p;
-   st_translate_fragment_program(st, stfp, NULL);
+   st->drawpix.z_shader = (struct st_fragment_program *) p;
+   st_translate_fragment_program(st, st->drawpix.z_shader, NULL);
 
-   return stfp;
+   return st->drawpix.z_shader;
 }
 
 
@@ -351,19 +228,20 @@ make_fragment_shader_z(struct st_context *st)
  * Create a simple vertex shader that just passes through the
  * vertex position and texcoord (and optionally, color).
  */
-struct st_vertex_program *
+static struct st_vertex_program *
 st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
 {
-   /* only make programs once and re-use */
-   static struct st_vertex_program *progs[2] = { NULL, NULL };
    GLcontext *ctx = st->ctx;
    struct st_vertex_program *stvp;
    struct gl_program *p;
    GLuint ic = 0;
 
-   if (progs[passColor])
-      return progs[passColor];
+   if (st->drawpix.vert_shaders[passColor])
+      return st->drawpix.vert_shaders[passColor];
 
+   /*
+    * Create shader now
+    */
    p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
    if (!p)
       return NULL;
@@ -417,9 +295,9 @@ st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
    }
 
    stvp = (struct st_vertex_program *) p;
-   st_translate_vertex_program(st, stvp, NULL);
+   st_translate_vertex_program(st, stvp, NULL, NULL, NULL);
 
-   progs[passColor] = stvp;
+   st->drawpix.vert_shaders[passColor] = stvp;
 
    return stvp;
 }
@@ -467,16 +345,16 @@ make_texture(struct st_context *st,
    assert(pipeFormat);
    cpp = st_sizeof_format(pipeFormat);
 
-   pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height,
-                         1, 0);
-   if (!pt)
+   pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+   if (!pixels)
       return NULL;
 
-   if (unpack->BufferObj && unpack->BufferObj->Name) {
-      /*
-      pt->region = buffer_object_region(unpack->BufferObj);
-      */
-      printf("st_DrawPixels (sourcing from PBO not implemented yet)\n");
+   pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height,
+                         1, 0,
+                          PIPE_TEXTURE_USAGE_SAMPLER);
+   if (!pt) {
+      _mesa_unmap_drawpix_pbo(ctx, unpack);
+      return NULL;
    }
 
    {
@@ -489,10 +367,12 @@ make_texture(struct st_context *st,
       /* we'll do pixel transfer in a fragment shader */
       ctx->_ImageTransferState = 0x0;
 
-      surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
+      surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
+                                        PIPE_BUFFER_USAGE_CPU_WRITE);
 
       /* map texture surface */
-      dest = pipe_surface_map(surface);
+      dest = screen->surface_map(screen, surface,
+                                 PIPE_BUFFER_USAGE_CPU_WRITE);
 
       /* Put image into texture surface.
        * Note that the image is actually going to be upside down in
@@ -503,7 +383,7 @@ make_texture(struct st_context *st,
                                     mformat,          /* gl_texture_format */
                                     dest,             /* dest */
                                     0, 0, 0,          /* dstX/Y/Zoffset */
-                                    surface->pitch * cpp, /* dstRowStride, bytes */
+                                    surface->stride,  /* dstRowStride, bytes */
                                     &dstImageOffsets, /* dstImageOffsets */
                                     width, height, 1, /* size */
                                     format, type,     /* src format/type */
@@ -511,117 +391,115 @@ make_texture(struct st_context *st,
                                     unpack);
 
       /* unmap */
-      pipe_surface_unmap(surface);
+      screen->surface_unmap(screen, surface);
       pipe_surface_reference(&surface, NULL);
+
       assert(success);
 
       /* restore */
       ctx->_ImageTransferState = imageTransferStateSave;
    }
 
+   _mesa_unmap_drawpix_pbo(ctx, unpack);
+
    return pt;
 }
 
 
 /**
- * Draw textured quad.
+ * Draw quad with texcoords and optional color.
  * Coords are window coords with y=0=bottom.
+ * \param color  may be null
+ * \param invertTex  if true, flip texcoords vertically
  */
 static void
 draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
-          GLfloat x1, GLfloat y1, GLboolean invertTex)
+          GLfloat x1, GLfloat y1, const GLfloat *color,
+          GLboolean invertTex)
 {
-   GLfloat verts[4][2][4]; /* four verts, two attribs, XYZW */
-   GLuint i;
-   GLfloat sLeft = 0.0, sRight = 1.0;
-   GLfloat tTop = invertTex, tBot = 1.0 - tTop;
-
-   /* upper-left */
-   verts[0][0][0] = x0;    /* attr[0].x */
-   verts[0][0][1] = y0;    /* attr[0].y */
-   verts[0][1][0] = sLeft; /* attr[1].s */
-   verts[0][1][1] = tTop;  /* attr[1].t */
-
-   /* upper-right */
-   verts[1][0][0] = x1;
-   verts[1][0][1] = y0;
-   verts[1][1][0] = sRight;
-   verts[1][1][1] = tTop;
-
-   /* lower-right */
-   verts[2][0][0] = x1;
-   verts[2][0][1] = y1;
-   verts[2][1][0] = sRight;
-   verts[2][1][1] = tBot;
-
-   /* lower-left */
-   verts[3][0][0] = x0;
-   verts[3][0][1] = y1;
-   verts[3][1][0] = sLeft;
-   verts[3][1][1] = tBot;
-
-   /* same for all verts: */
-   for (i = 0; i < 4; i++) {
-      verts[i][0][2] = z;   /*Z*/
-      verts[i][0][3] = 1.0; /*W*/
-      verts[i][1][2] = 0.0; /*R*/
-      verts[i][1][3] = 1.0; /*Q*/
-   }
-
-   st_draw_vertices(ctx, PIPE_PRIM_QUADS, 4, (float *) verts, 2, GL_FALSE);
-}
-
-
-static void
-draw_quad_colored(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
-                  GLfloat x1, GLfloat y1, const GLfloat *color,
-                  GLboolean invertTex)
-{
-   GLfloat bias = ctx->st->bitmap_texcoord_bias;
+   struct st_context *st = ctx->st;
+   struct pipe_context *pipe = ctx->st->pipe;
    GLfloat verts[4][3][4]; /* four verts, three attribs, XYZW */
-   GLuint i;
-   GLfloat xBias = bias / (x1-x0);
-   GLfloat yBias = bias / (y1-y0);
-   GLfloat sLeft = 0.0 + xBias, sRight = 1.0 + xBias;
-   GLfloat tTop = invertTex - yBias, tBot = 1.0 - tTop - yBias;
-
-   /* upper-left */
-   verts[0][0][0] = x0;    /* attr[0].x */
-   verts[0][0][1] = y0;    /* attr[0].y */
-   verts[0][2][0] = sLeft; /* attr[2].s */
-   verts[0][2][1] = tTop;  /* attr[2].t */
-
-   /* upper-right */
-   verts[1][0][0] = x1;
-   verts[1][0][1] = y0;
-   verts[1][2][0] = sRight;
-   verts[1][2][1] = tTop;
-
-   /* lower-right */
-   verts[2][0][0] = x1;
-   verts[2][0][1] = y1;
-   verts[2][2][0] = sRight;
-   verts[2][2][1] = tBot;
-
-   /* lower-left */
-   verts[3][0][0] = x0;
-   verts[3][0][1] = y1;
-   verts[3][2][0] = sLeft;
-   verts[3][2][1] = tBot;
-
-   /* same for all verts: */
-   for (i = 0; i < 4; i++) {
-      verts[i][0][2] = z;   /*Z*/
-      verts[i][0][3] = 1.0; /*W*/
-      verts[i][1][0] = color[0];
-      verts[i][1][1] = color[1];
-      verts[i][1][2] = color[2];
-      verts[i][1][3] = color[3];
-      verts[i][2][2] = 0.0; /*R*/
-      verts[i][2][3] = 1.0; /*Q*/
+
+   /* setup vertex data */
+   {
+      const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
+      const GLfloat fb_width = (GLfloat) fb->Width;
+      const GLfloat fb_height = (GLfloat) fb->Height;
+      const GLfloat clip_x0 = x0 / fb_width * 2.0f - 1.0f;
+      const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f;
+      const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f;
+      const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f;
+      const GLfloat sLeft = 0.0f, sRight = 1.0f;
+      const GLfloat tTop = invertTex, tBot = 1.0f - tTop;
+      GLuint tex, i;
+
+      /* upper-left */
+      verts[0][0][0] = clip_x0;    /* v[0].attr[0].x */
+      verts[0][0][1] = clip_y0;    /* v[0].attr[0].y */
+
+      /* upper-right */
+      verts[1][0][0] = clip_x1;
+      verts[1][0][1] = clip_y0;
+
+      /* lower-right */
+      verts[2][0][0] = clip_x1;
+      verts[2][0][1] = clip_y1;
+
+      /* lower-left */
+      verts[3][0][0] = clip_x0;
+      verts[3][0][1] = clip_y1;
+
+      tex = color ? 2 : 1;
+      verts[0][tex][0] = sLeft; /* v[0].attr[tex].s */
+      verts[0][tex][1] = tTop;  /* v[0].attr[tex].t */
+      verts[1][tex][0] = sRight;
+      verts[1][tex][1] = tTop;
+      verts[2][tex][0] = sRight;
+      verts[2][tex][1] = tBot;
+      verts[3][tex][0] = sLeft;
+      verts[3][tex][1] = tBot;
+
+      /* same for all verts: */
+      if (color) {
+         for (i = 0; i < 4; i++) {
+            verts[i][0][2] = z;   /*Z*/
+            verts[i][0][3] = 1.0f; /*W*/
+            verts[i][1][0] = color[0];
+            verts[i][1][1] = color[1];
+            verts[i][1][2] = color[2];
+            verts[i][1][3] = color[3];
+            verts[i][2][2] = 0.0f; /*R*/
+            verts[i][2][3] = 1.0f; /*Q*/
+         }
+      }
+      else {
+         for (i = 0; i < 4; i++) {
+            verts[i][0][2] = z;   /*Z*/
+            verts[i][0][3] = 1.0f; /*W*/
+            verts[i][1][2] = 0.0f; /*R*/
+            verts[i][1][3] = 1.0f; /*Q*/
+         }
+      }
    }
 
-   st_draw_vertices(ctx, PIPE_PRIM_QUADS, 4, (float *) verts, 3, GL_FALSE);
+   {
+      struct pipe_buffer *buf;
+      ubyte *map;
+
+      /* allocate/load buffer object with vertex data */
+      buf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
+                               sizeof(verts));
+      map = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
+      memcpy(map, verts, sizeof(verts));
+      pipe_buffer_unmap(pipe->screen, buf);
+
+      util_draw_vertex_buffer(pipe, buf,
+                              PIPE_PRIM_QUADS,
+                              4,  /* verts */
+                              3); /* attribs/vert */
+      pipe_buffer_reference(pipe->screen, &buf, NULL);
+   }
 }
 
 
@@ -640,7 +518,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
    struct pipe_context *pipe = ctx->st->pipe;
    struct cso_context *cso = ctx->st->cso_context;
    GLfloat x0, y0, x1, y1;
-   GLuint maxSize;
+   GLsizei maxSize;
 
    /* limit checks */
    /* XXX if DrawPixels image is larger than max texture size, break
@@ -652,22 +530,25 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
 
    cso_save_rasterizer(cso);
    cso_save_viewport(cso);
+   cso_save_samplers(cso);
+   cso_save_sampler_textures(cso);
+   cso_save_fragment_shader(cso);
+   cso_save_vertex_shader(cso);
 
-   /* setup state: just scissor */
+   /* rasterizer state: just scissor */
    {
-      struct pipe_rasterizer_state  setup;
-      memset(&setup, 0, sizeof(setup));
-      if (ctx->Scissor.Enabled)
-         setup.scissor = 1;
-
-      cso_set_rasterizer(cso, &setup);
+      struct pipe_rasterizer_state rasterizer;
+      memset(&rasterizer, 0, sizeof(rasterizer));
+      rasterizer.gl_rasterization_rules = 1;
+      rasterizer.scissor = ctx->Scissor.Enabled;
+      cso_set_rasterizer(cso, &rasterizer);
    }
 
    /* fragment shader state: TEX lookup program */
-   pipe->bind_fs_state(pipe, stfp->driver_shader);
+   cso_set_fragment_shader_handle(cso, stfp->driver_shader);
 
    /* vertex shader state: position + texcoord pass-through */
-   pipe->bind_vs_state(pipe, stvp->driver_shader);
+   cso_set_vertex_shader_handle(cso, stvp->driver_shader);
 
 
    /* texture sampling state: */
@@ -683,27 +564,36 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
       sampler.normalized_coords = 1;
 
       cso_single_sampler(cso, 0, &sampler);
+      if (st->pixel_xfer.pixelmap_enabled) {
+         cso_single_sampler(cso, 1, &sampler);
+      }
       cso_single_sampler_done(cso);
    }
 
    /* viewport state: viewport matching window dims */
    {
-      const float width = ctx->DrawBuffer->Width;
-      const float height = ctx->DrawBuffer->Height;
+      const float width = (float) ctx->DrawBuffer->Width;
+      const float height = (float) ctx->DrawBuffer->Height;
       struct pipe_viewport_state vp;
-      vp.scale[0] =  0.5 * width;
-      vp.scale[1] = -0.5 * height;
-      vp.scale[2] = 1.0;
-      vp.scale[3] = 1.0;
-      vp.translate[0] = 0.5 * width;
-      vp.translate[1] = 0.5 * height;
-      vp.translate[2] = 0.0;
-      vp.translate[3] = 0.0;
+      vp.scale[0] =  0.5f * width;
+      vp.scale[1] = -0.5f * height;
+      vp.scale[2] = 1.0f;
+      vp.scale[3] = 1.0f;
+      vp.translate[0] = 0.5f * width;
+      vp.translate[1] = 0.5f * height;
+      vp.translate[2] = 0.0f;
+      vp.translate[3] = 0.0f;
       cso_set_viewport(cso, &vp);
    }
 
    /* texture state: */
-   {
+   if (st->pixel_xfer.pixelmap_enabled) {
+      struct pipe_texture *textures[2];
+      textures[0] = pt;
+      textures[1] = st->pixel_xfer.pixelmap_texture;
+      pipe->set_sampler_textures(pipe, 2, textures);
+   }
+   else {
       pipe->set_sampler_textures(pipe, 1, &pt);
    }
 
@@ -711,29 +601,21 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
     * Recall that these coords are transformed by the current
     * vertex shader and viewport transformation.
     */
-   x0 = x;
+   x0 = (GLfloat) x;
    x1 = x + width * ctx->Pixel.ZoomX;
-   y0 = y;
+   y0 = (GLfloat) y;
    y1 = y + height * ctx->Pixel.ZoomY;
-
-   /* draw textured quad */
-   if (color)
-      draw_quad_colored(ctx, x0, y0, z, x1, y1, color, invertTex);
-   else
-      draw_quad(ctx, x0, y0, z, x1, y1, invertTex);
-
+   //if(!color)
+   draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex);
+   //else
+   //printf("skip draw quad\n");
    /* restore state */
    cso_restore_rasterizer(cso);
    cso_restore_viewport(cso);
-   /* shaders don't go through cso yet */
-   pipe->bind_fs_state(pipe, st->fp->driver_shader);
-   pipe->bind_vs_state(pipe, st->vp->driver_shader);
-
-   cso_set_rasterizer(cso, &st->state.rasterizer);
-   cso_set_samplers(cso, PIPE_MAX_SAMPLERS,
-                 (const struct pipe_sampler_state **) st->state.sampler_list);
-   pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
-                              ctx->st->state.sampler_texture);
+   cso_restore_samplers(cso);
+   cso_restore_sampler_textures(cso);
+   cso_restore_fragment_shader(cso);
+   cso_restore_vertex_shader(cso);
 }
 
 
@@ -856,15 +738,23 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
 {
    struct st_context *st = ctx->st;
    struct pipe_context *pipe = st->pipe;
-   struct pipe_surface *ps = st->state.framebuffer.zsbuf;
+   struct pipe_screen *screen = pipe->screen;
+   struct st_renderbuffer *strb;
+   struct pipe_surface *ps;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
    GLint skipPixels;
    ubyte *stmap;
 
-   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
+   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+   strb = st_renderbuffer(ctx->DrawBuffer->
+                          Attachment[BUFFER_STENCIL].Renderbuffer);
+   ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
+                                PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* map the stencil buffer */
-   stmap = pipe_surface_map(ps);
+   stmap = screen->surface_map(screen, ps, 
+                               PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* if width > MAX_WIDTH, have to process image in chunks */
    skipPixels = 0;
@@ -895,15 +785,15 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
             }
 
             switch (ps->format) {
-            case PIPE_FORMAT_U_S8:
+            case PIPE_FORMAT_S8_UNORM:
                {
-                  ubyte *dest = stmap + spanY * ps->pitch + spanX;
+                  ubyte *dest = stmap + spanY * ps->stride + spanX;
                   memcpy(dest, values, spanWidth);
                }
                break;
             case PIPE_FORMAT_S8Z24_UNORM:
                {
-                  uint *dest = (uint *) stmap + spanY * ps->pitch + spanX;
+                  uint *dest = (uint *) (stmap + spanY * ps->stride + spanX*4);
                   GLint k;
                   for (k = 0; k < spanWidth; k++) {
                      uint p = dest[k];
@@ -921,7 +811,8 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
    }
 
    /* unmap the stencil buffer */
-   pipe_surface_unmap(ps);
+   screen->surface_unmap(screen, ps);
+   pipe_surface_reference(&ps, NULL);
 }
 
 
@@ -945,6 +836,9 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       return;
    }
 
+   _mesa_set_vp_override( ctx, TRUE );
+   _mesa_update_state( ctx );
+
    st_validate_state(st);
 
    if (format == GL_DEPTH_COMPONENT) {
@@ -967,9 +861,9 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
 
    bufferFormat = ps->format;
 
-   if (any_fragment_ops(st) ||
+   if (1/*any_fragment_ops(st) ||
        any_pixel_transfer_ops(st) ||
-       !compatible_formats(format, type, ps->format)) {
+       !compatible_formats(format, type, ps->format)*/) {
       /* textured quad */
       struct pipe_texture *pt
          = make_texture(ctx->st, width, height, format, type, unpack, pixels);
@@ -984,166 +878,21 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       /* blit */
       draw_blit(st, width, height, format, type, pixels);
    }
-}
-
-
-
-/**
- * Create a texture which represents a bitmap image.
- */
-static struct pipe_texture *
-make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
-                    const struct gl_pixelstore_attrib *unpack,
-                    const GLubyte *bitmap)
-{
-   struct pipe_context *pipe = ctx->st->pipe;
-   struct pipe_screen *screen = pipe->screen;
-   struct pipe_surface *surface;
-   uint format = 0, cpp, comp;
-   ubyte *dest;
-   struct pipe_texture *pt;
-   int row, col;
-
-   /* find a texture format we know */
-   if (screen->is_format_supported( screen, PIPE_FORMAT_U_I8, PIPE_TEXTURE )) {
-      format = PIPE_FORMAT_U_I8;
-      cpp = 1;
-      comp = 0;
-   }
-   else if (screen->is_format_supported( screen, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_TEXTURE )) {
-      format = PIPE_FORMAT_A8R8G8B8_UNORM;
-      cpp = 4;
-      comp = 3; /* alpha channel */ /*XXX little-endian dependency */
-   }
-   else {
-      /* XXX support more formats */
-      assert( 0 );
-   }
-
-   /**
-    * Create a texture.
-    */
-   pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, width, height,
-                         1, 0);
-   if (!pt)
-      return NULL;
-
-   if (unpack->BufferObj && unpack->BufferObj->Name) {
-      /*
-      pt->region = buffer_object_region(unpack->BufferObj);
-      */
-      printf("st_Bitmap (sourcing from PBO not implemented yet)\n");
-   }
-
-   surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
-
-   /* map texture surface */
-   dest = pipe_surface_map(surface);
-
-   /* Put image into texture surface.
-    * Note that the image is actually going to be upside down in
-    * the texture.  We deal with that with texcoords.
-    */
-
-   for (row = 0; row < height; row++) {
-      const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
-                 bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
-      ubyte *destRow = dest + row * surface->pitch * cpp;
-
-      if (unpack->LsbFirst) {
-         /* Lsb first */
-         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
-         for (col = 0; col < width; col++) {
-
-            /* set texel to 255 if bit is set */
-            destRow[comp] = (*src & mask) ? 255 : 0;
-            destRow += cpp;
-
-            if (mask == 128U) {
-               src++;
-               mask = 1U;
-            }
-            else {
-               mask = mask << 1;
-            }
-         }
-
-         /* get ready for next row */
-         if (mask != 1)
-            src++;
-      }
-      else {
-         /* Msb first */
-         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
-         for (col = 0; col < width; col++) {
-
-            /* set texel to 255 if bit is set */
-            destRow[comp] =(*src & mask) ? 255 : 0;
-            destRow += cpp;
 
-            if (mask == 1U) {
-               src++;
-               mask = 128U;
-            }
-            else {
-               mask = mask >> 1;
-            }
-         }
-
-         /* get ready for next row */
-         if (mask != 128)
-            src++;
-      }
-
-   } /* row */
-
-   /* Release surface */
-   pipe_surface_unmap(surface);
-   pipe_surface_reference(&surface, NULL);
-
-   pt->format = format;
-
-   return pt;
+   _mesa_set_vp_override( ctx, FALSE );
 }
 
 
 
-static void
-st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
-          const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap )
-{
-   struct st_fragment_program *stfp;
-   struct st_vertex_program *stvp;
-   struct st_context *st = ctx->st;
-   struct pipe_texture *pt;
-
-   stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
-   stfp = combined_bitmap_fragment_program(ctx);
-
-   st_validate_state(st);
-
-   pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
-   if (pt) {
-      draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
-                         width, height, 1.0, 1.0,
-                         pt, stvp, stfp,
-                         ctx->Current.RasterColor, GL_FALSE);
-
-      pipe_texture_reference(&pt, NULL);
-   }
-}
-
-
 static void
 copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                     GLsizei width, GLsizei height,
                     GLint dstx, GLint dsty)
 {
-   struct st_renderbuffer *rbRead = st_renderbuffer(ctx->ReadBuffer->_StencilBuffer);
    struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
-   struct pipe_surface *psRead = rbRead->surface;
-   struct pipe_surface *psDraw = rbDraw->surface;
-   ubyte *readMap, *drawMap;
+   struct pipe_screen *screen = ctx->st->pipe->screen;
+   struct pipe_surface *psDraw;
+   ubyte *drawMap;
    ubyte *buffer;
    int i;
 
@@ -1153,14 +902,19 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
       return;
    }
 
-   /* map the stencil buffers */
-   readMap = pipe_surface_map(psRead);
-   drawMap = pipe_surface_map(psDraw);
-
    /* this will do stencil pixel transfer ops */
    st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE,
                           &ctx->DefaultPacking, buffer);
 
+   psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0,
+                                    PIPE_BUFFER_USAGE_CPU_WRITE);
+
+   assert(psDraw->block.width == 1);
+   assert(psDraw->block.height == 1);
+   
+   /* map the stencil buffer */
+   drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE);
+
    /* draw */
    /* XXX PixelZoom not handled yet */
    for (i = 0; i < height; i++) {
@@ -1174,7 +928,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
          y = ctx->DrawBuffer->Height - y - 1;
       }
 
-      dst = drawMap + (y * psDraw->pitch + dstx) * psDraw->cpp;
+      dst = drawMap + y * psDraw->stride + dstx * psDraw->block.size;
       src = buffer + i * width;
 
       switch (psDraw->format) {
@@ -1188,7 +942,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
             }
          }
          break;
-      case PIPE_FORMAT_U_S8:
+      case PIPE_FORMAT_S8_UNORM:
          memcpy(dst, src, width);
          break;
       default:
@@ -1198,9 +952,9 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
 
    free(buffer);
 
-   /* unmap the stencil buffers */
-   pipe_surface_unmap(psRead);
-   pipe_surface_unmap(psDraw);
+   /* unmap the stencil buffer */
+   screen->surface_unmap(screen, psDraw);
+   pipe_surface_reference(&psDraw, NULL);
 }
 
 
@@ -1215,14 +969,13 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    struct st_renderbuffer *rbRead;
    struct st_vertex_program *stvp;
    struct st_fragment_program *stfp;
-   struct pipe_surface *psRead;
    struct pipe_surface *psTex;
    struct pipe_texture *pt;
    GLfloat *color;
    enum pipe_format srcFormat, texFormat;
 
    /* make sure rendering has completed */
-   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
+   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
 
    st_validate_state(st);
 
@@ -1233,7 +986,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    if (type == GL_COLOR) {
-      rbRead = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
+      rbRead = st_get_color_read_renderbuffer(ctx);
       color = NULL;
       stfp = combined_drawpix_fragment_program(ctx);
       stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE);
@@ -1246,85 +999,87 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
       stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
    }
 
-   psRead = rbRead->surface;
-   srcFormat = psRead->format;
+   srcFormat = rbRead->texture->format;
 
-   if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE)) {
+   if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE_2D, 
+                                   PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
       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??? */
+         texFormat = st_choose_format(pipe, GL_DEPTH_COMPONENT, PIPE_TEXTURE_2D, 
+                                      PIPE_TEXTURE_USAGE_DEPTH_STENCIL);
+         assert(texFormat != PIPE_FORMAT_NONE); /* XXX no depth texture formats??? */
       }
       else {
-         /* todo */
-         assert(0);
+         /* default color format */
+         texFormat = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE_2D, 
+                                      PIPE_TEXTURE_USAGE_SAMPLER);
+         assert(texFormat != PIPE_FORMAT_NONE);
       }
    }
 
    pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
-                          width, height, 1, 0);
+                          width, height, 1, 0,
+                          PIPE_TEXTURE_USAGE_SAMPLER);
    if (!pt)
       return;
 
-   psTex = screen->get_tex_surface(screen, pt, 0, 0, 0);
-
    if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
       srcy = ctx->DrawBuffer->Height - srcy - height;
    }
 
-   /* For some drivers (like Xlib) it's not possible to treat the
-    * 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 && srcFormat == texFormat) {
+   if (srcFormat == texFormat) {
       /* copy source framebuffer surface into mipmap/texture */
+      struct pipe_surface *psRead = screen->get_tex_surface(screen,
+                                       rbRead->texture, 0, 0, 0,
+                                       PIPE_BUFFER_USAGE_GPU_READ);
+      psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 
+                                      PIPE_BUFFER_USAGE_GPU_WRITE );
       pipe->surface_copy(pipe,
                          FALSE,
                         psTex, /* dest */
                         0, 0, /* destx/y */
                         psRead,
                         srcx, srcy, width, height);
+      pipe_surface_reference(&psRead, NULL);
    }
-   else if (type == GL_COLOR) {
-      /* alternate path using get/put_tile() */
-      GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+   else {
+      /* CPU-based fallback/conversion */
+      struct pipe_surface *psRead = screen->get_tex_surface(screen,
+                                       rbRead->texture, 0, 0, 0,
+                                       PIPE_BUFFER_USAGE_CPU_READ);
 
-      pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf);
-      pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf);
+      psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 
+                                      PIPE_BUFFER_USAGE_CPU_WRITE );
 
-      free(buf);
-   }
-   else {
-      /* GL_DEPTH */
-      GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
-      pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf);
-      pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf);
-      free(buf);
+      if (type == GL_COLOR) {
+         /* alternate path using get/put_tile() */
+         GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+
+         pipe_get_tile_rgba(psRead, srcx, srcy, width, height, buf);
+         pipe_put_tile_rgba(psTex, 0, 0, width, height, buf);
+
+         free(buf);
+      }
+      else {
+         /* GL_DEPTH */
+         GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
+         pipe_get_tile_z(psRead, srcx, srcy, width, height, buf);
+         pipe_put_tile_z(psTex, 0, 0, width, height, buf);
+         free(buf);
+      }
+      pipe_surface_reference(&psRead, NULL);
    }
 
+   pipe_surface_reference(&psTex, NULL);
+
    /* draw textured quad */
    draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
                       width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
                       pt, stvp, stfp, color, GL_TRUE);
 
-   pipe_surface_reference(&psTex, NULL);
    pipe_texture_reference(&pt, NULL);
 }
 
@@ -1334,5 +1089,16 @@ void st_init_drawpixels_functions(struct dd_function_table *functions)
 {
    functions->DrawPixels = st_DrawPixels;
    functions->CopyPixels = st_CopyPixels;
-   functions->Bitmap = st_Bitmap;
 }
+
+
+void
+st_destroy_drawpix(struct st_context *st)
+{
+   st_reference_fragprog(st, &st->drawpix.z_shader, NULL);
+   st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
+   st_reference_vertprog(st, &st->drawpix.vert_shaders[0], NULL);
+   st_reference_vertprog(st, &st->drawpix.vert_shaders[1], NULL);
+}
+
+