DRI2: Drop sarea, implement swap buffers in the X server.
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_image.c
index 4f5f75d0492a280e1f865bc81ad17e6719de36b5..187fcc7dcb885030440b82da3435641c13c7b4f8 100644 (file)
@@ -14,6 +14,7 @@
 #include "texformat.h"
 #include "texobj.h"
 #include "texstore.h"
+#include "teximage.h"
 
 #include "intel_context.h"
 #include "intel_mipmap_tree.h"
@@ -22,6 +23,7 @@
 #include "intel_tex.h"
 #include "intel_ioctl.h"
 #include "intel_blit.h"
+#include "intel_fbo.h"
 
 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
 
@@ -73,7 +75,10 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
 
    DBG("%s\n", __FUNCTION__);
 
-   if (intelImage->base.Border)
+   if (intelImage->base.Border ||
+       ((intelImage->base._BaseFormat == GL_DEPTH_COMPONENT) && 
+        ((intelObj->base.WrapS == GL_CLAMP_TO_BORDER) ||
+         (intelObj->base.WrapT == GL_CLAMP_TO_BORDER))))
       return;
 
    if (intelImage->level > intelObj->base.BaseLevel &&
@@ -233,8 +238,6 @@ try_pbo_upload(struct intel_context *intel,
                         dst_stride, dst_buffer, dst_offset, GL_FALSE,
                         0, 0, 0, 0, width, height,
                        GL_COPY);
-
-      intel_batchbuffer_flush(intel->batch);
    }
    UNLOCK_HARDWARE(intel);
 
@@ -308,7 +311,7 @@ intelTexImage(GLcontext * ctx,
    GLint postConvWidth = width;
    GLint postConvHeight = height;
    GLint texelBytes, sizeInBytes;
-   GLuint dstRowStride;
+   GLuint dstRowStride, srcRowStride = texImage->RowStride;
 
 
    DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
@@ -346,8 +349,10 @@ intelTexImage(GLcontext * ctx,
         postConvWidth = 32 / texelBytes;
         texImage->RowStride = postConvWidth;
       }
-      
-      assert(texImage->RowStride == postConvWidth);
+
+      if (!intelImage->mt) {      
+         assert(texImage->RowStride == postConvWidth);
+      }
    }
 
    /* Release the reference to a potentially orphaned buffer.   
@@ -358,7 +363,8 @@ intelTexImage(GLcontext * ctx,
       assert(!texImage->Data);
    }
    else if (texImage->Data) {
-      _mesa_align_free(texImage->Data);
+      _mesa_free_texmemory(texImage->Data);
+      texImage->Data = NULL;
    }
 
    /* If this is the only texture image in the tree, could call
@@ -392,10 +398,25 @@ intelTexImage(GLcontext * ctx,
 
       intel_miptree_reference(&intelImage->mt, intelObj->mt);
       assert(intelImage->mt);
-   }
+   } else if (intelImage->base.Border == 0) {
+      int comp_byte = 0;
+
+      if (intelImage->base.IsCompressed) {
+        comp_byte =
+           intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
+      }
 
-   if (!intelImage->mt)
-      DBG("XXX: Image did not fit into tree - storing in local memory!\n");
+      /* Didn't fit in the object miptree, but it's suitable for inclusion in
+       * a miptree, so create one just for our level and store it in the image.
+       * It'll get moved into the object miptree at validate time.
+       */
+      intelImage->mt = intel_miptree_create(intel, target, internalFormat,
+                                           level, level,
+                                           width, height, depth,
+                                           intelImage->base.TexFormat->TexelBytes,
+                                           comp_byte);
+
+   }
 
    /* PBO fastpaths:
     */
@@ -454,8 +475,6 @@ intelTexImage(GLcontext * ctx,
                                           format, type,
                                           pixels, unpack, "glTexImage");
    }
-   if (!pixels)
-      return;
 
    LOCK_HARDWARE(intel);
 
@@ -481,7 +500,7 @@ intelTexImage(GLcontext * ctx,
          sizeInBytes = depth * dstRowStride * postConvHeight;
       }
 
-      texImage->Data = malloc(sizeInBytes);
+      texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
    }
 
    DBG("Upload image %dx%dx%d row_len %d "
@@ -492,24 +511,34 @@ intelTexImage(GLcontext * ctx,
     * the blitter to copy.  Or, use the hardware to do the format
     * conversion and copy:
     */
-   if (compressed) {
-     memcpy(texImage->Data, pixels, imageSize);
-   } else if (!texImage->TexFormat->StoreImage(ctx, dims, 
-                                              texImage->_BaseFormat, 
-                                              texImage->TexFormat, 
-                                              texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
-                                              dstRowStride,
-                                              texImage->ImageOffsets,
-                                              width, height, depth,
-                                              format, type, pixels, unpack)) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+   if (pixels) {
+       if (compressed) {
+          if (intelImage->mt) {
+              struct intel_region *dst = intelImage->mt->region;
+              _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch,
+                              0, 0,
+                              intelImage->mt->level[level].width,
+                              intelImage->mt->level[level].height/4,
+                              pixels,
+                              srcRowStride,
+                              0, 0);
+          } else
+              memcpy(texImage->Data, pixels, imageSize);
+       } else if (!texImage->TexFormat->StoreImage(ctx, dims, 
+                                                  texImage->_BaseFormat, 
+                                                  texImage->TexFormat, 
+                                                  texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
+                                                  dstRowStride,
+                                                  texImage->ImageOffsets,
+                                                  width, height, depth,
+                                                  format, type, pixels, unpack)) {
+          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+       }
    }
 
    /* GL_SGIS_generate_mipmap */
    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      intel_generate_mipmap(ctx, target,
-                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
-                            texObj);
+      intel_generate_mipmap(ctx, target, texObj);
    }
 
    _mesa_unmap_teximage_pbo(ctx, unpack);
@@ -652,20 +681,18 @@ intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
 void
 intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
                           GLvoid *pixels,
-                          const struct gl_texture_object *texObj,
-                          const struct gl_texture_image *texImage)
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage)
 {
    intel_get_tex_image(ctx, target, level, 0, 0, pixels,
                       texObj, texImage, 1);
-
 }
 
 void
 intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
                  unsigned long long offset, GLint depth, GLuint pitch)
 {
-   struct intel_context *intel = (struct intel_context*)
-      ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
+   struct intel_context *intel = pDRICtx->driverPrivate;
    struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname);
    struct intel_texture_object *intelObj = intel_texture_object(tObj);
 
@@ -682,3 +709,65 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
    if (offset)
       intelObj->textureOffset = offset;
 }
+
+void
+intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
+{
+   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+   struct intel_context *intel = pDRICtx->driverPrivate;
+   struct intel_texture_object *intelObj;
+   struct intel_texture_image *intelImage;
+   struct intel_mipmap_tree *mt;
+   struct intel_renderbuffer *rb;
+   struct gl_texture_unit *texUnit;
+   struct gl_texture_object *texObj;
+   struct gl_texture_image *texImage;
+   int level = 0, type, format, internalFormat;
+
+   texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit];
+   texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target);
+   intelObj = intel_texture_object(texObj);
+
+   if (!intelObj)
+      return;
+
+   intel_update_renderbuffers(pDRICtx, dPriv);
+
+   rb = intel_fb->color_rb[0];
+   type = GL_BGRA;
+   format = GL_UNSIGNED_BYTE;
+   internalFormat = (rb->region->cpp == 3 ? 3 : 4);
+
+   mt = intel_miptree_create_for_region(intel, target,
+                                       internalFormat,
+                                       0, 0, rb->region, 1, 0);
+   if (mt == NULL)
+       return;
+
+   _mesa_lock_texture(&intel->ctx, texObj);
+
+   if (intelObj->mt)
+      intel_miptree_release(intel, &intelObj->mt);
+
+   intelObj->mt = mt;
+   texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level);
+   _mesa_init_teximage_fields(&intel->ctx, target, texImage,
+                             rb->region->pitch, rb->region->height, 1,
+                             0, internalFormat);
+
+   intelImage = intel_texture_image(texImage);
+   intelImage->face = target_to_face(target);
+   intelImage->level = level;
+   texImage->TexFormat = intelChooseTextureFormat(&intel->ctx, internalFormat,
+                                                  type, format);
+   _mesa_set_fetch_functions(texImage, 2);
+   texImage->RowStride = rb->region->pitch;
+   intel_miptree_reference(&intelImage->mt, intelObj->mt);
+
+   if (!intel_miptree_match_image(intelObj->mt, &intelImage->base,
+                                 intelImage->face, intelImage->level)) {
+          fprintf(stderr, "miptree doesn't match image\n");
+   }
+
+   _mesa_unlock_texture(&intel->ctx, texObj);
+}