Merge branch 'mesa_7_6_branch'
[mesa.git] / src / mesa / state_tracker / st_cb_drawpixels.c
index 99f3ba678bb5a68a5c1e6464f66472a9e3689ff5..1d33e81c2c9c889efc0d82476c9c50097ca52322 100644 (file)
 #include "main/bufferobj.h"
 #include "main/macros.h"
 #include "main/texformat.h"
+#include "main/texstore.h"
 #include "main/state.h"
 #include "shader/program.h"
 #include "shader/prog_parameter.h"
 #include "shader/prog_print.h"
 
+#include "st_debug.h"
 #include "st_context.h"
 #include "st_atom.h"
 #include "st_atom_constbuf.h"
@@ -61,6 +63,7 @@
 #include "util/u_tile.h"
 #include "util/u_draw_quad.h"
 #include "util/u_math.h"
+#include "util/u_rect.h"
 #include "shader/prog_instruction.h"
 #include "cso_cache/cso_context.h"
 
@@ -337,7 +340,7 @@ make_texture(struct st_context *st,
    GLcontext *ctx = st->ctx;
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
-   const struct gl_texture_format *mformat;
+   gl_format mformat;
    struct pipe_texture *pt;
    enum pipe_format pipeFormat;
    GLuint cpp;
@@ -349,7 +352,7 @@ make_texture(struct st_context *st,
    mformat = st_ChooseTextureFormat(ctx, baseFormat, format, type);
    assert(mformat);
 
-   pipeFormat = st_mesa_format_to_pipe_format(mformat->MesaFormat);
+   pipeFormat = st_mesa_format_to_pipe_format(mformat);
    assert(pipeFormat);
    cpp = st_sizeof_format(pipeFormat);
 
@@ -402,21 +405,22 @@ make_texture(struct st_context *st,
       /* map texture transfer */
       dest = screen->transfer_map(screen, transfer);
 
+
       /* Put image into texture transfer.
        * Note that the image is actually going to be upside down in
        * the texture.  We deal with that with texcoords.
        */
-      success = mformat->StoreImage(ctx, 2,           /* dims */
-                                    baseFormat,       /* baseInternalFormat */
-                                    mformat,          /* gl_texture_format */
-                                    dest,             /* dest */
-                                    0, 0, 0,          /* dstX/Y/Zoffset */
-                                    transfer->stride, /* dstRowStride, bytes */
-                                    &dstImageOffsets, /* dstImageOffsets */
-                                    width, height, 1, /* size */
-                                    format, type,     /* src format/type */
-                                    pixels,           /* data source */
-                                    unpack);
+      success = _mesa_texstore(ctx, 2,           /* dims */
+                               baseFormat,       /* baseInternalFormat */
+                               mformat,          /* gl_format */
+                               dest,             /* dest */
+                               0, 0, 0,          /* dstX/Y/Zoffset */
+                               transfer->stride, /* dstRowStride, bytes */
+                               &dstImageOffsets, /* dstImageOffsets */
+                               width, height, 1, /* size */
+                               format, type,     /* src format/type */
+                               pixels,           /* data source */
+                               unpack);
 
       /* unmap */
       screen->transfer_unmap(screen, transfer);
@@ -598,15 +602,15 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
 
    /* viewport state: viewport matching window dims */
    {
-      const float width = (float) ctx->DrawBuffer->Width;
-      const float height = (float) ctx->DrawBuffer->Height;
+      const float w = (float) ctx->DrawBuffer->Width;
+      const float h = (float) ctx->DrawBuffer->Height;
       struct pipe_viewport_state vp;
-      vp.scale[0] =  0.5f * width;
-      vp.scale[1] = -0.5f * height;
+      vp.scale[0] =  0.5f * w;
+      vp.scale[1] = -0.5f * h;
       vp.scale[2] = 1.0f;
       vp.scale[3] = 1.0f;
-      vp.translate[0] = 0.5f * width;
-      vp.translate[1] = 0.5f * height;
+      vp.translate[0] = 0.5f * w;
+      vp.translate[1] = 0.5f * h;
       vp.translate[2] = 0.0f;
       vp.translate[3] = 0.0f;
       cso_set_viewport(cso, &vp);
@@ -661,6 +665,15 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
    GLint skipPixels;
    ubyte *stmap;
+   struct gl_pixelstore_attrib clippedUnpack = *unpack;
+
+   if (!zoom) {
+      if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
+                                 &clippedUnpack)) {
+         /* totally clipped */
+         return;
+      }
+   }
 
    strb = st_renderbuffer(ctx->DrawBuffer->
                           Attachment[BUFFER_STENCIL].Renderbuffer);
@@ -681,7 +694,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
 
    stmap = screen->transfer_map(screen, pt);
 
-   pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
+   pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
    assert(pixels);
 
    /* if width > MAX_WIDTH, have to process image in chunks */
@@ -694,17 +707,18 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
          GLubyte sValues[MAX_WIDTH];
          GLuint zValues[MAX_WIDTH];
          GLenum destType = GL_UNSIGNED_BYTE;
-         const GLvoid *source = _mesa_image_address2d(unpack, pixels,
+         const GLvoid *source = _mesa_image_address2d(&clippedUnpack, pixels,
                                                       width, height,
                                                       format, type,
                                                       row, skipPixels);
          _mesa_unpack_stencil_span(ctx, spanWidth, destType, sValues,
-                                   type, source, unpack,
+                                   type, source, &clippedUnpack,
                                    ctx->_ImageTransferState);
 
          if (format == GL_DEPTH_STENCIL) {
             _mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, zValues,
-                                    (1 << 24) - 1, type, source, unpack);
+                                    (1 << 24) - 1, type, source,
+                                    &clippedUnpack);
          }
 
          if (zoom) {
@@ -775,7 +789,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
       skipPixels += spanWidth;
    }
 
-   _mesa_unmap_pbo_source(ctx, unpack);
+   _mesa_unmap_pbo_source(ctx, &clippedUnpack);
 
    /* unmap the stencil buffer */
    screen->transfer_unmap(screen, pt);
@@ -1014,13 +1028,14 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    else {
       /* srcFormat can't be used as a texture format */
       if (type == GL_DEPTH) {
-         texFormat = st_choose_format(pipe, GL_DEPTH_COMPONENT, PIPE_TEXTURE_2D, 
+         texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
+                                      PIPE_TEXTURE_2D, 
                                       PIPE_TEXTURE_USAGE_DEPTH_STENCIL);
          assert(texFormat != PIPE_FORMAT_NONE); /* XXX no depth texture formats??? */
       }
       else {
          /* default color format */
-         texFormat = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE_2D, 
+         texFormat = st_choose_format(screen, GL_RGBA, PIPE_TEXTURE_2D, 
                                       PIPE_TEXTURE_USAGE_SAMPLER);
          assert(texFormat != PIPE_FORMAT_NONE);
       }
@@ -1073,11 +1088,19 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
                                        PIPE_BUFFER_USAGE_GPU_READ);
       struct pipe_surface *psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 
                                       PIPE_BUFFER_USAGE_GPU_WRITE );
-      pipe->surface_copy(pipe,
-                        psTex, /* dest */
-                        0, 0, /* destx/y */
-                        psRead,
-                        srcx, srcy, width, height);
+      if (pipe->surface_copy) {
+         pipe->surface_copy(pipe,
+                            psTex, /* dest */
+                            0, 0, /* destx/y */
+                            psRead,
+                            srcx, srcy, width, height);
+      } else {
+         util_surface_copy(pipe, FALSE,
+                           psTex,
+                           0, 0,
+                           psRead,
+                           srcx, srcy, width, height);
+      }
       pipe_surface_reference(&psRead, NULL); 
       pipe_surface_reference(&psTex, NULL);
    }
@@ -1090,6 +1113,9 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
       struct pipe_transfer *ptTex;
       enum pipe_transfer_usage transfer_usage;
 
+      if (ST_DEBUG & DEBUG_FALLBACK)
+         debug_printf("%s: fallback processing\n", __FUNCTION__);
+
       if (type == GL_DEPTH && pf_is_depth_and_stencil(pt->format))
          transfer_usage = PIPE_TRANSFER_READ_WRITE;
       else