radeon: texture/renderbuffer overhaul.
authorDave Airlie <airlied@redhat.com>
Fri, 11 Nov 2011 16:13:06 +0000 (16:13 +0000)
committerDave Airlie <airlied@redhat.com>
Mon, 5 Dec 2011 14:36:19 +0000 (14:36 +0000)
This could have been split up better, but the driver is just broken now,
so bisecting the brokenness is going to be painful no matter what.

This adds renderbuffer mapping/unmapping along with texture image allocation.
It drops all the old texture upload paths, some of which could possible be
reimplemented with the blitter later.

It also redoes the span code paths to use its own set of image mapping handlers,
along with removing the tiling decode paths for the color buffers, since
we now hope to use the blitter for this.

Signed-off-by: Dave Airlie <airlied@redhat.com>
13 files changed:
src/mesa/drivers/dri/r200/r200_blit.c
src/mesa/drivers/dri/r200/r200_blit.h
src/mesa/drivers/dri/radeon/radeon_blit.c
src/mesa/drivers/dri/radeon/radeon_blit.h
src/mesa/drivers/dri/radeon/radeon_common_context.h
src/mesa/drivers/dri/radeon/radeon_fbo.c
src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
src/mesa/drivers/dri/radeon/radeon_pixel_read.c
src/mesa/drivers/dri/radeon/radeon_span.c
src/mesa/drivers/dri/radeon/radeon_tex_copy.c
src/mesa/drivers/dri/radeon/radeon_texture.c
src/mesa/drivers/dri/radeon/radeon_texture.h

index 487bb5b78e1bfc472027deae9bd74bf5af57aaf1..04ab6d07def72f53b3ce53b14d17e94fcc63c71d 100644 (file)
@@ -38,7 +38,7 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
 }
 
 /* common formats supported as both textures and render targets */
-unsigned r200_check_blit(gl_format mesa_format)
+unsigned r200_check_blit(gl_format mesa_format, uint32_t dst_pitch)
 {
     /* XXX others?  BE/LE? */
     switch (mesa_format) {
@@ -58,6 +58,12 @@ unsigned r200_check_blit(gl_format mesa_format)
            return 0;
     }
 
+    /* Rendering to small buffer doesn't work.
+     * Looks like a hw limitation.
+     */
+    if (dst_pitch < 32)
+            return 0;
+
     /* ??? */
     if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
            return 0;
@@ -467,19 +473,13 @@ unsigned r200_blit(struct gl_context *ctx,
 {
     struct r200_context *r200 = R200_CONTEXT(ctx);
 
-    if (!r200_check_blit(dst_mesaformat))
+    if (!r200_check_blit(dst_mesaformat, dst_pitch))
         return GL_FALSE;
 
     /* Make sure that colorbuffer has even width - hw limitation */
     if (dst_pitch % 2 > 0)
         ++dst_pitch;
 
-    /* Rendering to small buffer doesn't work.
-     * Looks like a hw limitation.
-     */
-    if (dst_pitch < 32)
-        return GL_FALSE;
-
     /* Need to clamp the region size to make sure
      * we don't read outside of the source buffer
      * or write outside of the destination buffer.
index 56018b9c0eaf7334c4c24dd94d745bd26384f649..fb5dacbe87018f672d544189a4a4a1586f22446e 100644 (file)
@@ -30,7 +30,7 @@
 
 void r200_blit_init(struct r200_context *r200);
 
-unsigned r200_check_blit(gl_format mesa_format);
+unsigned r200_check_blit(gl_format mesa_format, uint32_t dst_pitch);
 
 unsigned r200_blit(struct gl_context *ctx,
                    struct radeon_bo *src_bo,
index 330e1abdfe57709284af64bcd639f578e9b549ca..b84f2fa9f2b9bb7851310896471b6bc77b129b28 100644 (file)
@@ -38,7 +38,7 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
 }
 
 /* common formats supported as both textures and render targets */
-unsigned r100_check_blit(gl_format mesa_format)
+unsigned r100_check_blit(gl_format mesa_format, uint32_t dst_pitch)
 {
     /* XXX others?  BE/LE? */
     switch (mesa_format) {
@@ -55,6 +55,12 @@ unsigned r100_check_blit(gl_format mesa_format)
            return 0;
     }
 
+    /* Rendering to small buffer doesn't work.
+     * Looks like a hw limitation.
+     */
+    if (dst_pitch < 32)
+        return 0;
+
     /* ??? */
     if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
            return 0;
@@ -344,19 +350,13 @@ unsigned r100_blit(struct gl_context *ctx,
 {
     struct r100_context *r100 = R100_CONTEXT(ctx);
 
-    if (!r100_check_blit(dst_mesaformat))
+    if (!r100_check_blit(dst_mesaformat, dst_pitch))
         return GL_FALSE;
 
     /* Make sure that colorbuffer has even width - hw limitation */
     if (dst_pitch % 2 > 0)
         ++dst_pitch;
 
-    /* Rendering to small buffer doesn't work.
-     * Looks like a hw limitation.
-     */
-    if (dst_pitch < 32)
-        return GL_FALSE;
-
     /* Need to clamp the region size to make sure
      * we don't read outside of the source buffer
      * or write outside of the destination buffer.
index 5e5c73481a645c454abe3382e9faa9e12f4cd4a7..4fac4afe8891e4b34c96db4305fbb66677fab846 100644 (file)
@@ -30,7 +30,7 @@
 
 void r100_blit_init(struct r100_context *r100);
 
-unsigned r100_check_blit(gl_format mesa_format);
+unsigned r100_check_blit(gl_format mesa_format, uint32_t dst_pitch);
 
 unsigned r100_blit(struct gl_context *ctx,
                    struct radeon_bo *src_bo,
index 6de9f8a37b5159a6ad9fffc548a08f79acf1f2a1..b8c6bf00ebce7d7eae2c691402931afa5800bcf3 100644 (file)
@@ -89,6 +89,7 @@ struct radeon_renderbuffer
        struct radeon_bo *map_bo;
        GLbitfield map_mode;
        int map_x, map_y, map_w, map_h;
+       int map_pitch;
 
        uint32_t draw_offset; /* FBO */
        /* boo Xorg 6.8.2 compat */
@@ -174,6 +175,7 @@ struct _radeon_texture_image {
         */
        struct _radeon_mipmap_tree *mt;
        struct radeon_bo *bo;
+       GLboolean used_as_render_target;
 };
 
 
@@ -481,7 +483,7 @@ struct radeon_context {
           void (*free_context)(struct gl_context *ctx);
           void (*emit_query_finish)(radeonContextPtr radeon);
           void (*update_scissor)(struct gl_context *ctx);
-          unsigned (*check_blit)(gl_format mesa_format);
+          unsigned (*check_blit)(gl_format mesa_format, uint32_t dst_pitch);
           unsigned (*blit)(struct gl_context *ctx,
                         struct radeon_bo *src_bo,
                         intptr_t src_offset,
index 9967fe5139e14f3241cd3b97cb14f4214f86bdb7..5aad67f1a7525c665d345385022d88fd90cad6a2 100644 (file)
@@ -82,56 +82,96 @@ radeon_map_renderbuffer(struct gl_context *ctx,
    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    GLubyte *map;
    GLboolean ok;
-   int stride, ret;
-
-   assert(rrb && rrb->bo);
-
-   /* Make a temporary buffer and blit the current contents of the renderbuffer
-    * out to it.  This gives us linear access to the buffer, instead of having
-    * to do detiling in software.
-    */
-   assert(!rrb->map_bo);
-   rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0,
-                               rrb->pitch * h, 4,
-                               RADEON_GEM_DOMAIN_GTT, 0);
+   int stride, flip_stride;
+   int ret;
+   int src_x, src_y;
+
+   if (!rrb || !rrb->bo) {
+          *out_map = NULL;
+          *out_stride = 0;
+          return;
+   }
+
    rrb->map_mode = mode;
    rrb->map_x = x;
    rrb->map_y = y;
    rrb->map_w = w;
    rrb->map_h = h;
+   rrb->map_pitch = rrb->pitch;
+
+   ok = rmesa->vtbl.check_blit(rb->Format, rrb->pitch / rrb->cpp);
+   if (ok) {
+       if (rb->Name) {
+          src_x = x;
+          src_y = y;
+       } else {
+          src_x = x;
+          src_y = rrb->base.Height - y - h;
+       }
+
+       /* Make a temporary buffer and blit the current contents of the renderbuffer
+       * out to it.  This gives us linear access to the buffer, instead of having
+       * to do detiling in software.
+       */
+
+       rrb->map_pitch = rrb->pitch;
+
+       assert(!rrb->map_bo);
+       rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0,
+                                   rrb->map_pitch * h, 4,
+                                   RADEON_GEM_DOMAIN_GTT, 0);
+       
+       ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
+                            rb->Format, rrb->pitch / rrb->cpp,
+                            rb->Width, rb->Height,
+                            src_x, src_y,
+                            rrb->map_bo, 0,
+                            rb->Format, rrb->map_pitch / rrb->cpp,
+                            w, h,
+                            0, 0,
+                            w, h,
+                            GL_FALSE);
+       assert(ok);
+
+       ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
+       assert(!ret);
+
+       map = rrb->map_bo->ptr;
+
+       if (rb->Name) {
+          *out_map = map;
+          *out_stride = rrb->map_pitch;
+       } else {
+          *out_map = map + (h - 1) * rrb->map_pitch;
+          *out_stride = -rrb->map_pitch;
+       }
+       return;
+   }
+
+   /* sw fallback flush stuff */
+   if (radeon_bo_is_referenced_by_cs(rrb->bo, rmesa->cmdbuf.cs)) {
+      radeon_firevertices(rmesa);
+   }
 
-   ok = rmesa->vtbl.check_blit(rb->Format);
-   assert(ok);
-
-   ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
-                        rb->Format, rrb->pitch / rrb->cpp,
-                        rb->Width, rb->Height,
-                        x, y,
-                        rrb->map_bo, 0,
-                        rb->Format, rrb->pitch / rrb->cpp,
-                        w, h,
-                        0, 0,
-                        w, h,
-                        GL_FALSE);
-   assert(ok);
-
-   radeon_bo_wait(rrb->map_bo);
-   ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
+   ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
    assert(!ret);
 
-   map = rrb->map_bo->ptr;
-   stride = rrb->pitch;
+   map = rrb->bo->ptr;
+   stride = rrb->map_pitch;
 
    if (rb->Name == 0) {
-      map += stride * (rb->Height - 1);
-      stride = -stride;
+      y = rb->Height - 1 - y;
+      flip_stride = -stride;
+   } else {
+      flip_stride = stride;
+      map += rrb->draw_offset;
    }
 
-   map += x * _mesa_get_format_bytes(rb->Format);
+   map += x * rrb->cpp;
    map += (int)y * stride;
 
    *out_map = map;
-   *out_stride = stride;
+   *out_stride = flip_stride;
 }
 
 static void
@@ -142,11 +182,17 @@ radeon_unmap_renderbuffer(struct gl_context *ctx,
    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    GLboolean ok;
 
+   if (!rrb->map_bo) {
+          if (rrb->bo)
+                  radeon_bo_unmap(rrb->bo);
+          return;
+   }
+
    radeon_bo_unmap(rrb->map_bo);
 
    if (rrb->map_mode & GL_MAP_WRITE_BIT) {
       ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0,
-                           rb->Format, rrb->pitch / rrb->cpp,
+                           rb->Format, rrb->map_pitch / rrb->cpp,
                            rrb->map_w, rrb->map_h,
                            0, 0,
                            rrb->bo, rrb->draw_offset,
@@ -627,7 +673,7 @@ radeon_render_texture(struct gl_context * ctx,
 
    radeon_image = (radeon_texture_image *)newImage;
 
-   if (!radeon_image->mt || newImage->Border != 0) {
+   if (!radeon_image->mt) {
       /* Fallback on drawing to a texture without a miptree.
        */
       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
@@ -681,6 +727,7 @@ radeon_render_texture(struct gl_context * ctx,
     * the image we are rendering to */
    rrb->draw_offset = imageOffset;
    rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride;
+   radeon_image->used_as_render_target = GL_TRUE;
 
    /* update drawing region, etc */
    radeon_draw_buffer(ctx, fb);
@@ -690,7 +737,16 @@ static void
 radeon_finish_render_texture(struct gl_context * ctx,
                             struct gl_renderbuffer_attachment *att)
 {
-
+    struct gl_texture_object *tex_obj = att->Texture;
+    struct gl_texture_image *image =
+       tex_obj->Image[att->CubeMapFace][att->TextureLevel];
+    radeon_texture_image *radeon_image = (radeon_texture_image *)image;
+    
+    if (radeon_image)
+       radeon_image->used_as_render_target = GL_FALSE;
+
+    if (ctx->Driver.Flush)
+        ctx->Driver.Flush(ctx); /* +r6/r7 */
 }
 static void
 radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
index 05daf1cec4344b33b3210ce3669308b534c2149b..23af9aca6ce99e14c4d7ce77ba1a69813c377ea9 100644 (file)
@@ -185,9 +185,9 @@ static void calculate_miptree_layout(radeonContextPtr rmesa, radeon_mipmap_tree
 /**
  * Create a new mipmap tree, calculate its layout and allocate memory.
  */
-static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa,
-               GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
-               GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits)
+radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa,
+                                         GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
+                                         GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits)
 {
        radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree);
 
@@ -298,13 +298,10 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj,
  * given face and level.
  */
 GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
-               struct gl_texture_image *texImage, GLuint face, GLuint level)
+                                      struct gl_texture_image *texImage)
 {
        radeon_mipmap_level *lvl;
-
-       if (face >= mt->faces)
-               return GL_FALSE;
-
+       GLuint level = texImage->Level;
        if (texImage->TexFormat != mt->mesaFormat)
                return GL_FALSE;
 
@@ -332,7 +329,7 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g
 
        mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel];
        firstImage = texObj->Image[0][texObj->BaseLevel];
-       numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1);
+       numLevels = MIN2(texObj->_MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1);
 
        if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) {
                fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj);
@@ -372,7 +369,6 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t)
        struct gl_texture_object *texObj = &t->base;
        struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel];
        GLuint numLevels;
-
        assert(!t->mt);
 
        if (!texImg) {
@@ -544,27 +540,19 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
 {
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
        radeonTexObj *t = radeon_tex_obj(texObj);
+       radeon_mipmap_tree *dst_miptree;
 
        if (t->validated || t->image_override) {
                return GL_TRUE;
        }
 
-       if (texObj->Image[0][texObj->BaseLevel]->Border > 0)
-               return GL_FALSE;
-
-       _mesa_test_texobj_completeness(rmesa->glCtx, texObj);
-       if (!texObj->_Complete) {
-               return GL_FALSE;
-       }
-
        calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod);
 
        radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
                        "%s: Validating texture %p now, minLod = %d, maxLod = %d\n",
                        __FUNCTION__, texObj ,t->minLod, t->maxLod);
 
-       radeon_mipmap_tree *dst_miptree;
-       dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base.MaxLevel);
+       dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base._MaxLevel);
 
        radeon_miptree_unreference(&t->mt);
        if (!dst_miptree) {
@@ -591,7 +579,7 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
                                "Checking image level %d, face %d, mt %p ... ",
                                level, face, img->mt);
                        
-                       if (img->mt != t->mt) {
+                       if (img->mt != t->mt && !img->used_as_render_target) {
                                radeon_print(RADEON_TEXTURE, RADEON_TRACE,
                                        "MIGRATING\n");
 
index c0c52f0ff9a271611663bbce5b3275b1cc08e31e..74007ffdebc77b05d64d1c6cbc5306dc15499dd0 100644 (file)
@@ -84,7 +84,8 @@ void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr);
 void radeon_miptree_unreference(radeon_mipmap_tree **ptr);
 
 GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
-               struct gl_texture_image *texImage, GLuint face, GLuint level);
+                                      struct gl_texture_image *texImage);
+                                      
 void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t);
 GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt,
                                   GLuint face, GLuint level);
@@ -98,4 +99,8 @@ unsigned get_texture_image_size(
                unsigned height,
                unsigned depth,
                unsigned tiling);
+
+radeon_mipmap_tree *radeon_miptree_create(radeonContextPtr rmesa,
+                                         GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
+                                         GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits);
 #endif /* __RADEON_MIPMAP_TREE_H_ */
index 9f6124034d9a3c983e05043376fe7a5075acca73..68e3114989dfb0ea34d81b4d949f15199c2d0f56 100644 (file)
@@ -105,7 +105,7 @@ do_blit_readpixels(struct gl_context * ctx,
     }
 
     if (dst_format == MESA_FORMAT_NONE ||
-        !radeon->vtbl.check_blit(dst_format) || !radeon->vtbl.blit) {
+        !radeon->vtbl.check_blit(dst_format, rrb->pitch / rrb->cpp) || !radeon->vtbl.blit) {
         return GL_FALSE;
     }
 
index ecc3befdbfeabbb7d929a78eb5c399153ed1ad77..b83d152091c256d7993e61edc09f946b180028a5 100644 (file)
@@ -216,25 +216,25 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
  */
 #define LOCAL_VARS                                             \
    struct radeon_renderbuffer *rrb = (void *) rb;              \
-   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;                        \
-   const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
    int minx = 0, miny = 0;                                             \
    int maxx = rb->Width;                                               \
    int maxy = rb->Height;                                              \
+   void *buf = rb->Data;                                               \
+   int pitch = rb->RowStride * rrb->cpp;                               \
    GLuint p;                                           \
    (void)p;
 
 #define LOCAL_DEPTH_VARS                               \
    struct radeon_renderbuffer *rrb = (void *) rb;      \
-   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;                        \
-   const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
    int minx = 0, miny = 0;                                             \
+   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;                 \
+   const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1; \
    int maxx = rb->Width;                                               \
    int maxy = rb->Height;
 
 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
 
-#define Y_FLIP(_y) ((_y) * yScale + yBias)
+#define Y_FLIP(_y) (_y)
 
 #define HW_LOCK()
 #define HW_UNLOCK()
@@ -249,108 +249,78 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
  */
 #define SPANTMP_PIXEL_FMT GL_RGB
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
-
 #define TAG(x)    radeon##x##_RGB565
 #define TAG2(x,y) radeon##x##_RGB565##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
 #include "spantmp2.h"
 
 #define SPANTMP_PIXEL_FMT GL_RGB
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV
-
 #define TAG(x)    radeon##x##_RGB565_REV
 #define TAG2(x,y) radeon##x##_RGB565_REV##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
 #include "spantmp2.h"
 
 /* 16 bit, ARGB1555 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
-
 #define TAG(x)    radeon##x##_ARGB1555
 #define TAG2(x,y) radeon##x##_ARGB1555##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
 #include "spantmp2.h"
 
 #define SPANTMP_PIXEL_FMT GL_BGRA
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5
-
 #define TAG(x)    radeon##x##_ARGB1555_REV
 #define TAG2(x,y) radeon##x##_ARGB1555_REV##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
 #include "spantmp2.h"
 
 /* 16 bit, RGBA4 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
-
 #define TAG(x)    radeon##x##_ARGB4444
 #define TAG2(x,y) radeon##x##_ARGB4444##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
 #include "spantmp2.h"
 
 #define SPANTMP_PIXEL_FMT GL_BGRA
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4
-
 #define TAG(x)    radeon##x##_ARGB4444_REV
 #define TAG2(x,y) radeon##x##_ARGB4444_REV##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
 #include "spantmp2.h"
 
 /* 32 bit, xRGB8888 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
-
 #define TAG(x)    radeon##x##_xRGB8888
 #define TAG2(x,y) radeon##x##_xRGB8888##y
-#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)) | 0xff000000))
-#define PUT_VALUE(_x, _y, d) { \
-   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y );            \
-   *_ptr = d;                                                          \
-} while (0)
 #include "spantmp2.h"
 
 /* 32 bit, ARGB8888 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
-
 #define TAG(x)    radeon##x##_ARGB8888
 #define TAG2(x,y) radeon##x##_ARGB8888##y
-#define GET_VALUE(_x, _y) (*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)))
-#define PUT_VALUE(_x, _y, d) { \
-   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y );            \
-   *_ptr = d;                                                          \
-} while (0)
 #include "spantmp2.h"
 
 /* 32 bit, BGRx8888 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
-
 #define TAG(x)    radeon##x##_BGRx8888
 #define TAG2(x,y) radeon##x##_BGRx8888##y
-#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)) | 0x000000ff))
-#define PUT_VALUE(_x, _y, d) { \
-   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y );            \
-   *_ptr = d;                                                          \
-} while (0)
 #include "spantmp2.h"
 
 /* 32 bit, BGRA8888 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
-
 #define TAG(x)    radeon##x##_BGRA8888
 #define TAG2(x,y) radeon##x##_BGRA8888##y
-#define GET_PTR(X,Y) radeon_ptr_4byte(rrb, (X), (Y))
 #include "spantmp2.h"
 
+#undef Y_FLIP
+#define Y_FLIP(_y) ((_y) * yScale + yBias)
 /* ================================================================
  * Depth buffer
  */
@@ -509,77 +479,69 @@ do {                                                                      \
 #define TAG(x) radeon##x##_s8_z24
 #include "stenciltmp.h"
 
-
-static void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
+static void
+radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb)
 {
        struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
-       int r;
+       GLubyte *map;
+       int stride;
 
-       if (rrb == NULL || !rrb->bo)
+       if (!rb || !rrb)
                return;
 
-       radeon_print(RADEON_MEMORY, RADEON_TRACE,
-               "%s( rb %p, flag %s )\n",
-               __func__, rb, flag ? "true":"false");
-
-       if (flag) {
-               radeon_bo_wait(rrb->bo);
-               r = radeon_bo_map(rrb->bo, 1);
-               if (r) {
-                       fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
-                               __FUNCTION__, r);
-               }
+       ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height,
+                                   GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
+                                   &map, &stride);
 
-               radeonSetSpanFunctions(rrb);
-       } else {
-               radeon_bo_unmap(rrb->bo);
-               rb->GetRow = NULL;
-               rb->PutRow = NULL;
-       }
+       rb->Data = map;
+       rb->RowStride = stride / _mesa_get_format_bytes(rb->Format);
+
+       radeonSetSpanFunctions(rrb);
+}
+
+static void
+radeon_renderbuffer_unmap(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+       struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+       if (!rb || !rrb)
+               return;
+
+       ctx->Driver.UnmapRenderbuffer(ctx, rb);
+
+       rb->GetRow = NULL;
+       rb->PutRow = NULL;
+       rb->Data = NULL;
+       rb->RowStride = 0;
 }
 
 static void
-radeon_map_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
-                            GLboolean map)
+radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
 {
        GLuint i, j;
 
        radeon_print(RADEON_MEMORY, RADEON_TRACE,
-               "%s( %p , fb %p, map %s )\n",
-               __func__, ctx, fb, map ? "true":"false");
+               "%s( %p , fb %p )\n",
+                    __func__, ctx, fb);
 
-       /* color draw buffers */
-       for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++)
-               map_unmap_rb(fb->_ColorDrawBuffers[j], map);
+       /* check for render to textures */
+       for (i = 0; i < BUFFER_COUNT; i++)
+               radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer);
 
-       map_unmap_rb(fb->_ColorReadBuffer, map);
+       radeon_check_front_buffer_rendering(ctx);
+}
 
-       /* check for render to textures */
-       for (i = 0; i < BUFFER_COUNT; i++) {
-               struct gl_renderbuffer_attachment *att =
-                       fb->Attachment + i;
-               struct gl_texture_object *tex = att->Texture;
-               if (tex) {
-                       /* Render to texture. Note that a mipmapped texture need not
-                        * be complete for render to texture, so we must restrict to
-                        * mapping only the attached image.
-                        */
-                       radeon_texture_image *image = get_radeon_texture_image(tex->Image[att->CubeMapFace][att->TextureLevel]);
-                       ASSERT(att->Renderbuffer);
-
-                       if (map)
-                               radeon_teximage_map(image, GL_TRUE);
-                       else
-                               radeon_teximage_unmap(image);
-               }
-       }
-       
-       /* depth buffer (Note wrapper!) */
-       if (fb->_DepthBuffer)
-               map_unmap_rb(fb->_DepthBuffer->Wrapped, map);
+static void
+radeon_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
+{
+       GLuint i, j;
 
-       if (fb->_StencilBuffer)
-               map_unmap_rb(fb->_StencilBuffer->Wrapped, map);
+       radeon_print(RADEON_MEMORY, RADEON_TRACE,
+               "%s( %p , fb %p)\n",
+                    __func__, ctx, fb);
+
+       /* check for render to textures */
+       for (i = 0; i < BUFFER_COUNT; i++)
+               radeon_renderbuffer_unmap(ctx, fb->Attachment[i].Renderbuffer);
 
        radeon_check_front_buffer_rendering(ctx);
 }
@@ -591,13 +553,16 @@ static void radeonSpanRenderStart(struct gl_context * ctx)
 
        radeon_firevertices(rmesa);
 
-       for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
-               if (ctx->Texture.Unit[i]._ReallyEnabled)
-                       radeonMapTexture(ctx, ctx->Texture.Unit[i]._Current);
-
-       radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_TRUE);
+       for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
+               if (ctx->Texture.Unit[i]._ReallyEnabled) {
+                       radeon_validate_texture_miptree(ctx, ctx->Texture.Unit[i]._Current);
+                       radeon_swrast_map_texture_images(ctx, ctx->Texture.Unit[i]._Current);
+               }
+       }
+       
+       radeon_map_framebuffer(ctx, ctx->DrawBuffer);
        if (ctx->ReadBuffer != ctx->DrawBuffer)
-               radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_TRUE);
+               radeon_map_framebuffer(ctx, ctx->ReadBuffer);
 }
 
 static void radeonSpanRenderFinish(struct gl_context * ctx)
@@ -608,11 +573,11 @@ static void radeonSpanRenderFinish(struct gl_context * ctx)
 
        for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
                if (ctx->Texture.Unit[i]._ReallyEnabled)
-                       radeonUnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
+                       radeon_swrast_unmap_texture_images(ctx, ctx->Texture.Unit[i]._Current);
 
-       radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_FALSE);
+       radeon_unmap_framebuffer(ctx, ctx->DrawBuffer);
        if (ctx->ReadBuffer != ctx->DrawBuffer)
-               radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_FALSE);
+               radeon_unmap_framebuffer(ctx, ctx->ReadBuffer);
 }
 
 void radeonInitSpanFuncs(struct gl_context * ctx)
index bc9015e574db8dfcfecc097001346d79f60d2237..ca0ac16170944a99399f662296214a62a36d2971 100644 (file)
@@ -101,7 +101,7 @@ do_copy_texsubimage(struct gl_context *ctx,
     dst_mesaformat = timg->base.Base.TexFormat;
     src_bpp = _mesa_get_format_bytes(src_mesaformat);
     dst_bpp = _mesa_get_format_bytes(dst_mesaformat);
-    if (!radeon->vtbl.check_blit(dst_mesaformat)) {
+    if (!radeon->vtbl.check_blit(dst_mesaformat, rrb->pitch / rrb->cpp)) {
            /* depth formats tend to be special */
            if (_mesa_get_format_bits(dst_mesaformat, GL_DEPTH_BITS) > 0)
                    return GL_FALSE;
index 178ff0925c3fb26cb1d8b2eb62b37094aeb5e3be..71eff75cc04684ab9ae678a4f6d0d4702d1a18b7 100644 (file)
 
 #include "radeon_mipmap_tree.h"
 
+static void teximage_assign_miptree(radeonContextPtr rmesa,
+                                   struct gl_texture_object *texObj,
+                                   struct gl_texture_image *texImage);
+
+static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
+                                                             struct gl_texture_object *texObj,
+                                                             struct gl_texture_image *texImage);
 
 void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
        GLuint numrows, GLuint rowsize)
@@ -94,6 +101,33 @@ radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img)
        _mesa_delete_texture_image(ctx, img);
 }
 
+static GLboolean
+radeonAllocTextureImageBuffer(struct gl_context *ctx,
+                             struct gl_texture_image *timage,
+                             gl_format format, GLsizei width,
+                             GLsizei height, GLsizei depth)
+{
+       radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+       radeon_texture_image *image = get_radeon_texture_image(timage);
+       struct gl_texture_object *texobj = timage->TexObject;
+       int slices;
+
+       ctx->Driver.FreeTextureImageBuffer(ctx, timage);
+
+       switch (texobj->Target) {
+       case GL_TEXTURE_3D:
+               slices = timage->Depth;
+               break;
+       default:
+               slices = 1;
+       }
+       assert(!image->base.ImageOffsets);
+       image->base.ImageOffsets = malloc(slices * sizeof(GLuint));
+       teximage_assign_miptree(rmesa, texobj, timage);
+                               
+       return GL_TRUE;
+}
+
 
 /**
  * Free memory associated with this texture image.
@@ -104,7 +138,6 @@ void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_imag
 
        if (image->mt) {
                radeon_miptree_unreference(&image->mt);
-               assert(!image->base.Buffer);
        } else {
                _swrast_free_texture_image_buffer(ctx, timage);
        }
@@ -173,91 +206,6 @@ void radeon_teximage_unmap(radeon_texture_image *image)
        }
 }
 
-static void map_override(struct gl_context *ctx, radeonTexObj *t)
-{
-       radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
-
-       radeon_bo_map(t->bo, GL_FALSE);
-
-       img->base.Data = t->bo->ptr;
-}
-
-static void unmap_override(struct gl_context *ctx, radeonTexObj *t)
-{
-       radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
-
-       radeon_bo_unmap(t->bo);
-
-       img->base.Data = NULL;
-}
-
-/**
- * Map a validated texture for reading during software rendering.
- */
-void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
-       radeonTexObj* t = radeon_tex_obj(texObj);
-       int face, level;
-
-       radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
-                       "%s(%p, tex %p)\n",
-                       __func__, ctx, texObj);
-
-       if (!radeon_validate_texture_miptree(ctx, texObj)) {
-               radeon_error("%s(%p, tex %p) Failed to validate miptree for "
-                       "sw fallback.\n",
-                       __func__, ctx, texObj);
-               return;
-       }
-
-       if (t->image_override && t->bo) {
-               radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
-                       "%s(%p, tex %p) Work around for missing miptree in r100.\n",
-                       __func__, ctx, texObj);
-
-               map_override(ctx, t);
-       }
-
-       /* for r100 3D sw fallbacks don't have mt */
-       if (!t->mt) {
-               radeon_warning("%s(%p, tex %p) No miptree in texture.\n",
-                       __func__, ctx, texObj);
-               return;
-       }
-
-       radeon_bo_map(t->mt->bo, GL_FALSE);
-       for(face = 0; face < t->mt->faces; ++face) {
-               for(level = t->minLod; level <= t->maxLod; ++level)
-                       teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
-       }
-}
-
-void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
-       radeonTexObj* t = radeon_tex_obj(texObj);
-       int face, level;
-
-       radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
-                       "%s(%p, tex %p)\n",
-                       __func__, ctx, texObj);
-
-       if (t->image_override && t->bo)
-               unmap_override(ctx, t);
-       /* for r100 3D sw fallbacks don't have mt */
-       if (!t->mt)
-         return;
-
-       for(face = 0; face < t->mt->faces; ++face) {
-               for(level = t->minLod; level <= t->maxLod; ++level) {
-                       radeon_texture_image *image =
-                               get_radeon_texture_image(texObj->Image[face][level]);
-                       image->base.Data = NULL;
-               }
-       }
-       radeon_bo_unmap(t->mt->bo);
-}
-
-
 /**
  * Map texture memory/buffer into user space.
  * Note: the region of interest parameters are ignored here.
@@ -286,7 +234,7 @@ radeon_map_texture_image(struct gl_context *ctx,
        _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
        assert(y % bh == 0);
        y /= bh;
-       height /= bh;
+       texel_size /= bw;
 
        if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
                radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
@@ -302,9 +250,11 @@ radeon_map_texture_image(struct gl_context *ctx,
                *stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texImage->TexObject->Target);
                *map = bo->ptr;
        } else if (likely(mt)) {
-               radeon_bo_map(mt->bo, write);
+               void *base;
                radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level];
-               void *base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset;
+                      
+               radeon_bo_map(mt->bo, write);
+               base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset;
 
                *stride = lvl->rowstride;
                *map = base + (slice * height) * *stride;
@@ -594,51 +544,24 @@ gl_format radeonChooseTextureFormat(struct gl_context * ctx,
 
 /** Check if given image is valid within current texture object.
  */
-static int image_matches_texture_obj(struct gl_texture_object *texObj,
-       struct gl_texture_image *texImage,
-       unsigned level)
-{
-       const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
-
-       if (!baseImage)
-               return 0;
-
-       if (level < texObj->BaseLevel || level > texObj->MaxLevel)
-               return 0;
-
-       const unsigned levelDiff = level - texObj->BaseLevel;
-       const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
-       const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
-       const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
-
-       return (texImage->Width == refWidth &&
-                       texImage->Height == refHeight &&
-                       texImage->Depth == refDepth);
-}
-
 static void teximage_assign_miptree(radeonContextPtr rmesa,
-       struct gl_texture_object *texObj,
-       struct gl_texture_image *texImage,
-       unsigned face,
-       unsigned level)
+                                   struct gl_texture_object *texObj,
+                                   struct gl_texture_image *texImage)
 {
        radeonTexObj *t = radeon_tex_obj(texObj);
        radeon_texture_image* image = get_radeon_texture_image(texImage);
 
-       /* Since miptree holds only images for levels <BaseLevel..MaxLevel>
-        * don't allocate the miptree if the teximage won't fit.
-        */
-       if (!image_matches_texture_obj(texObj, texImage, level))
-               return;
-
        /* Try using current miptree, or create new if there isn't any */
-       if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
+       if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage)) {
                radeon_miptree_unreference(&t->mt);
-               radeon_try_alloc_miptree(rmesa, t);
+               t->mt = radeon_miptree_create_for_teximage(rmesa,
+                                                          texObj,
+                                                          texImage);
+
                radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
-                               "%s: texObj %p, texImage %p, face %d, level %d, "
+                            "%s: texObj %p, texImage %p, "
                                "texObj miptree doesn't match, allocated new miptree %p\n",
-                               __FUNCTION__, texObj, texImage, face, level, t->mt);
+                               __FUNCTION__, texObj, texImage, t->mt);
        }
 
        /* Miptree alocation may have failed,
@@ -650,101 +573,6 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,
                                "%s Failed to allocate miptree.\n", __func__);
 }
 
-
-/**
- * Update a subregion of the given texture image.
- */
-static void radeon_store_teximage(struct gl_context* ctx, int dims,
-               GLint xoffset, GLint yoffset, GLint zoffset,
-               GLsizei width, GLsizei height, GLsizei depth,
-               GLsizei imageSize,
-               GLenum format, GLenum type,
-               const GLvoid * pixels,
-               const struct gl_pixelstore_attrib *packing,
-               struct gl_texture_object *texObj,
-               struct gl_texture_image *texImage,
-               int compressed)
-{
-       radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-       radeonTexObj *t = radeon_tex_obj(texObj);
-       radeon_texture_image* image = get_radeon_texture_image(texImage);
-       GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat);
-
-       GLuint dstRowStride;
-       GLuint alignedWidth;
-       GLint i;
-
-       radeon_print(RADEON_TEXTURE, RADEON_TRACE,
-                       "%s(%p, tex %p, image %p) compressed %d\n",
-                       __func__, ctx, texObj, texImage, compressed);
-
-       if (image->mt) {
-               dstRowStride = image->mt->levels[image->base.Base.Level].rowstride;
-       } else if (t->bo) {
-               /* TFP case */
-               dstRowStride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texObj->Target);
-       } else {
-               dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
-       }
-
-       assert(dstRowStride);
-
-       /* fill in the ImageOffsets array */
-       alignedWidth = dstRowStride / texel_size;
-       for (i = 0; i < texImage->Depth; ++i) {
-               image->base.ImageOffsets[i] = alignedWidth * texImage->Height * i;
-       }
-       /* and fill in RowStride (in texels) */
-       image->base.RowStride = alignedWidth;
-
-       radeon_teximage_map(image, GL_TRUE);
-
-       if (compressed) {
-               uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
-               GLubyte *img_start;
-
-               _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
-
-               if (!image->mt) {
-                       dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
-                       img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
-                                                                       texImage->TexFormat,
-                                                                       texImage->Width, image->base.Data);
-               }
-               else {
-                       uint32_t offset;
-                       offset = dstRowStride / texel_size * yoffset / block_height + xoffset / block_width;
-                       offset *= texel_size;
-                       img_start = image->base.Data + offset;
-               }
-               srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
-               bytesPerRow = srcRowStride;
-               rows = (height + block_height - 1) / block_height;
-
-               copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
-       }
-       else {
-               GLubyte *slices[512];
-               GLuint i;
-               assert(depth <= 512);
-               for (i = 0; i < depth; i++) {
-                       slices[i] = (GLubyte *) image->base.Data
-                               + image->base.ImageOffsets[i] * texel_size;
-               }
-               if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
-                                       texImage->TexFormat,
-                                       xoffset, yoffset, zoffset,
-                                       dstRowStride,
-                                       slices,
-                                       width, height, depth,
-                                       format, type, pixels, packing)) {
-                       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
-               }
-       }
-
-       radeon_teximage_unmap(image);
-}
-
 /**
  * All glTexImage calls go through this function.
  */
@@ -760,72 +588,10 @@ static void radeon_teximage(
        struct gl_texture_image *texImage,
        int compressed)
 {
-       radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-       radeonTexObj* t = radeon_tex_obj(texObj);
-       radeon_texture_image* image = get_radeon_texture_image(texImage);
-       GLuint face = _mesa_tex_target_to_face(target);
-
-       radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
-                       "%s %dd: texObj %p, texImage %p, face %d, level %d\n",
-                       __func__, dims, texObj, texImage, face, level);
-
-       t->validated = GL_FALSE;
-
-       radeonFreeTextureImageBuffer(ctx, texImage);
-
-       if (!t->bo) {
-               teximage_assign_miptree(rmesa, texObj, texImage, face, level);
-               if (!image->mt) {
-                       int size = _mesa_format_image_size(texImage->TexFormat,
-                                                               texImage->Width,
-                                                               texImage->Height,
-                                                               texImage->Depth);
-                       image->base.Buffer = _mesa_align_malloc(size, 512);
-
-                       radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
-                                       "%s %dd: texObj %p, texImage %p, "
-                                       " no miptree assigned, using local memory %p\n",
-                                       __func__, dims, texObj, texImage, image->base.Buffer);
-               }
-       }
-
-       {
-               struct radeon_bo *bo;
-               bo = !image->mt ? image->bo : image->mt->bo;
-               if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
-                       radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
-                               "%s Calling teximage for texture that is "
-                               "queued for GPU processing.\n",
-                               __func__);
-                       radeon_firevertices(rmesa);
-               }
-       }
-
-       image->base.ImageOffsets =
-               (GLuint *) malloc(texImage->Depth * sizeof(GLuint));
-
-
-       /* Upload texture image; note that the spec allows pixels to be NULL */
-       if (compressed) {
-               pixels = _mesa_validate_pbo_compressed_teximage(
-                       ctx, imageSize, pixels, packing, "glCompressedTexImage");
-       } else {
-               pixels = _mesa_validate_pbo_teximage(
-                       ctx, dims, width, height, depth,
-                       format, type, pixels, packing, "glTexImage");
-       }
-
-       if (pixels) {
-               radeon_store_teximage(ctx, dims,
-                       0, 0, 0,
-                       width, height, depth,
-                       imageSize, format, type,
-                       pixels, packing,
-                       texObj, texImage,
-                       compressed);
-       }
-
-       _mesa_unmap_teximage_pbo(ctx, packing);
+       _mesa_store_teximage3d(ctx, target, level, internalFormat,
+                              width, height, depth, 0,
+                              format, type, pixels,
+                              packing, texObj, texImage);
 }
 
 void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
@@ -853,17 +619,6 @@ void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
-void radeonCompressedTexImage2D(struct gl_context * ctx, GLenum target,
-                                    GLint level, GLint internalFormat,
-                                    GLint width, GLint height, GLint border,
-                                    GLsizei imageSize, const GLvoid * data,
-                                    struct gl_texture_object *texObj,
-                                    struct gl_texture_image *texImage)
-{
-       radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
-               imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
-}
-
 void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
                      GLint internalFormat,
                      GLint width, GLint height, GLint depth,
@@ -877,116 +632,6 @@ void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
-/**
- * All glTexSubImage calls go through this function.
- */
-static void radeon_texsubimage(struct gl_context* ctx, int dims, GLenum target, int level,
-               GLint xoffset, GLint yoffset, GLint zoffset,
-               GLsizei width, GLsizei height, GLsizei depth,
-               GLsizei imageSize,
-               GLenum format, GLenum type,
-               const GLvoid * pixels,
-               const struct gl_pixelstore_attrib *packing,
-               struct gl_texture_object *texObj,
-               struct gl_texture_image *texImage,
-               int compressed)
-{
-       radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-       radeonTexObj* t = radeon_tex_obj(texObj);
-       radeon_texture_image* image = get_radeon_texture_image(texImage);
-
-       radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
-                       "%s %dd: texObj %p, texImage %p, face %d, level %d\n",
-                       __func__, dims, texObj, texImage,
-                       _mesa_tex_target_to_face(target), level);
-       {
-               struct radeon_bo *bo;
-               bo = !image->mt ? image->bo : image->mt->bo;
-               if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
-                       radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
-                               "%s Calling texsubimage for texture that is "
-                               "queued for GPU processing.\n",
-                               __func__);
-                       radeon_firevertices(rmesa);
-               }
-       }
-
-
-       t->validated = GL_FALSE;
-       if (compressed) {
-               pixels = _mesa_validate_pbo_compressed_teximage(
-                       ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
-       } else {
-               pixels = _mesa_validate_pbo_teximage(ctx, dims,
-                       width, height, depth, format, type, pixels, packing, "glTexSubImage");
-       }
-
-       if (pixels) {
-               radeon_store_teximage(ctx, dims,
-                       xoffset, yoffset, zoffset,
-                       width, height, depth,
-                       imageSize, format, type,
-                       pixels, packing,
-                       texObj, texImage,
-                       compressed);
-       }
-
-       _mesa_unmap_teximage_pbo(ctx, packing);
-}
-
-void radeonTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
-                        GLint xoffset,
-                        GLsizei width,
-                        GLenum format, GLenum type,
-                        const GLvoid * pixels,
-                        const struct gl_pixelstore_attrib *packing,
-                        struct gl_texture_object *texObj,
-                        struct gl_texture_image *texImage)
-{
-       radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
-               format, type, pixels, packing, texObj, texImage, 0);
-}
-
-void radeonTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
-                        GLint xoffset, GLint yoffset,
-                        GLsizei width, GLsizei height,
-                        GLenum format, GLenum type,
-                        const GLvoid * pixels,
-                        const struct gl_pixelstore_attrib *packing,
-                        struct gl_texture_object *texObj,
-                        struct gl_texture_image *texImage)
-{
-       radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
-                          0, format, type, pixels, packing, texObj, texImage,
-                          0);
-}
-
-void radeonCompressedTexSubImage2D(struct gl_context * ctx, GLenum target,
-                                  GLint level, GLint xoffset,
-                                  GLint yoffset, GLsizei width,
-                                  GLsizei height, GLenum format,
-                                  GLsizei imageSize, const GLvoid * data,
-                                  struct gl_texture_object *texObj,
-                                  struct gl_texture_image *texImage)
-{
-       radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
-               imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
-}
-
-
-void radeonTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level,
-                        GLint xoffset, GLint yoffset, GLint zoffset,
-                        GLsizei width, GLsizei height, GLsizei depth,
-                        GLenum format, GLenum type,
-                        const GLvoid * pixels,
-                        const struct gl_pixelstore_attrib *packing,
-                        struct gl_texture_object *texObj,
-                        struct gl_texture_image *texImage)
-{
-       radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
-               format, type, pixels, packing, texObj, texImage, 0);
-}
-
 unsigned radeonIsFormatRenderable(gl_format mesa_format)
 {
        if (mesa_format == _radeon_texformat_argb8888 || mesa_format == _radeon_texformat_rgb565 ||
@@ -1059,8 +704,7 @@ void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target,
        radeon_bo_ref(image->bo);
        t->mt->bo = image->bo;
 
-       if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base,
-                                         radeonImage->base.Base.Face, 0))
+       if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base))
                fprintf(stderr, "miptree doesn't match image\n");
 }
 #endif
@@ -1101,9 +745,8 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
 {
        functions->NewTextureImage = radeonNewTextureImage;
        functions->DeleteTextureImage = radeonDeleteTextureImage;
+       functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer;
        functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer;
-       functions->MapTexture = radeonMapTexture;
-       functions->UnmapTexture = radeonUnmapTexture;
        functions->MapTextureImage = radeon_map_texture_image;
        functions->UnmapTextureImage = radeon_unmap_texture_image;
 
@@ -1112,11 +755,6 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
        functions->TexImage1D = radeonTexImage1D;
        functions->TexImage2D = radeonTexImage2D;
        functions->TexImage3D = radeonTexImage3D;
-       functions->TexSubImage1D = radeonTexSubImage1D;
-       functions->TexSubImage2D = radeonTexSubImage2D;
-       functions->TexSubImage3D = radeonTexSubImage3D;
-       functions->CompressedTexImage2D = radeonCompressedTexImage2D;
-       functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
 
        functions->CopyTexSubImage2D = radeonCopyTexSubImage2D;
 
@@ -1127,3 +765,133 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
 
        radeonInitTextureFormats();
 }
+
+static void
+radeon_swrast_map_image(radeonContextPtr rmesa,
+                       radeon_texture_image *image)
+{
+       GLuint level, face;
+       radeon_mipmap_tree *mt;
+       GLuint texel_size;
+       radeon_mipmap_level *lvl;
+       int rs;
+
+       if (!image || !image->mt)
+               return;
+
+       texel_size = _mesa_get_format_bytes(image->base.Base.TexFormat);
+       level = image->base.Base.Level;
+       face = image->base.Base.Face;
+       mt = image->mt;
+
+       lvl = &image->mt->levels[level];
+
+       rs = lvl->rowstride / texel_size;
+
+       radeon_bo_map(mt->bo, 1);
+       
+       image->base.Data = mt->bo->ptr + lvl->faces[face].offset;
+       if (mt->target == GL_TEXTURE_3D) {
+               int i;
+
+               for (i = 0; i < mt->levels[level].depth; i++)
+                       image->base.ImageOffsets[i] = rs * lvl->height * i;
+       }
+       image->base.RowStride = rs;
+}
+
+static void
+radeon_swrast_unmap_image(radeonContextPtr rmesa,
+                         radeon_texture_image *image)
+{
+       if (image && image->mt) {
+               image->base.Data = NULL;
+               radeon_bo_unmap(image->mt->bo);
+       }
+}
+
+void
+radeon_swrast_map_texture_images(struct gl_context *ctx,
+                                struct gl_texture_object *texObj)
+{
+       radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+       GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
+       int i, face;
+
+       for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) {
+               for (face = 0; face < nr_faces; face++) {
+                       radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]);
+                       radeon_swrast_map_image(rmesa, image);
+               }
+       }
+}
+
+void
+radeon_swrast_unmap_texture_images(struct gl_context *ctx,
+                                  struct gl_texture_object *texObj)
+{
+       radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+       GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
+       int i, face;
+
+       for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) {
+               for (face = 0; face < nr_faces; face++) {
+                       radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]);
+                       radeon_swrast_unmap_image(rmesa, image);
+               }
+       }
+       
+}
+
+static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
+                                                      struct gl_texture_object *texObj,
+                                                      struct gl_texture_image *texImage)
+{
+       radeonTexObj *t = radeon_tex_obj(texObj);
+       GLuint firstLevel;
+       GLuint lastLevel;
+       int width, height, depth;
+       int i;
+
+       width = texImage->Width;
+       height = texImage->Height;
+       depth = texImage->Depth;
+
+       if (texImage->Level > texObj->BaseLevel &&
+           (width == 1 ||
+            (texObj->Target != GL_TEXTURE_1D && height == 1) ||
+            (texObj->Target == GL_TEXTURE_3D && depth == 1))) {
+               /* For this combination, we're at some lower mipmap level and
+                * some important dimension is 1.  We can't extrapolate up to a
+                * likely base level width/height/depth for a full mipmap stack
+                * from this info, so just allocate this one level.
+                */
+               firstLevel = texImage->Level;
+               lastLevel = texImage->Level;
+       } else {
+               if (texImage->Level < texObj->BaseLevel)
+                       firstLevel = 0;
+               else
+                       firstLevel = texObj->BaseLevel;
+
+               for (i = texImage->Level; i > firstLevel; i--) {
+                       width <<= 1;
+                       if (height != 1)
+                               height <<= 1;
+                       if (depth != 1)
+                               depth <<= 1;
+               }
+               if ((texObj->Sampler.MinFilter == GL_NEAREST ||
+                    texObj->Sampler.MinFilter == GL_LINEAR) &&
+                   texImage->Level == firstLevel) {
+                       lastLevel = firstLevel;
+               } else {
+                       lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth));
+               }
+       }
+
+       return  radeon_miptree_create(rmesa, texObj->Target,
+                                     texImage->TexFormat, firstLevel, lastLevel - firstLevel + 1,
+                                     width, height, depth, 
+                                     t->tile_bits);
+}                                   
index 0fa48bd1091e4e159d0735c224e1cb39e8f0c21d..f1af109707fdaf8269074c76b53fd0bd191fcbe8 100644 (file)
@@ -49,10 +49,12 @@ void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_imag
 
 void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable);
 void radeon_teximage_unmap(radeon_texture_image *image);
-void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj);
-void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj);
 int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_object *texObj);
 
+
+void radeon_swrast_map_texture_images(struct gl_context *ctx, struct gl_texture_object *texObj);
+void radeon_swrast_unmap_texture_images(struct gl_context *ctx, struct gl_texture_object *texObj);
+
 gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx,
                                          GLint internalFormat,
                                          GLenum format,