Move compiler.h and imports.h/c from src/mesa/main into src/util
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_fbo.c
index 63986058356a79d8efd03ddd0f1e1c9620e11915..e04ae54ad809752205e6879d78e57cf0b6d7c795 100644 (file)
@@ -18,7 +18,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -26,7 +26,7 @@
  **************************************************************************/
 
 
-#include "main/imports.h"
+#include "util/imports.h"
 #include "main/macros.h"
 #include "main/mtypes.h"
 #include "main/enums.h"
@@ -34,7 +34,7 @@
 #include "main/framebuffer.h"
 #include "main/renderbuffer.h"
 #include "main/context.h"
-#include "main/texrender.h"
+#include "swrast/swrast.h"
 #include "drivers/common/meta.h"
 
 #include "radeon_common.h"
                 printf(__VA_ARGS__);                      \
 } while(0)
 
-static struct gl_framebuffer *
-radeon_new_framebuffer(GLcontext *ctx, GLuint name)
-{
-  return _mesa_new_framebuffer(ctx, name);
-}
-
 static void
-radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
+radeon_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
 {
   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
 
@@ -61,50 +55,431 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
                "%s(rb %p, rrb %p) \n",
                __func__, rb, rrb);
 
-  ASSERT(rrb);
+  assert(rrb);
 
   if (rrb && rrb->bo) {
     radeon_bo_unref(rrb->bo);
   }
-  free(rrb);
+  _mesa_delete_renderbuffer(ctx, rb);
 }
 
-static void *
-radeon_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb,
-                  GLint x, GLint y)
+#if defined(RADEON_R100)
+static GLuint get_depth_z32(const struct radeon_renderbuffer * rrb,
+                              GLint x, GLint y)
 {
-  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
-               "%s(%p, rb %p) \n",
-               __func__, ctx, rb);
+    GLuint ba, address = 0;
+
+    ba = (y >> 4) * (rrb->pitch >> 6) + (x >> 4);
+
+    address |= (x & 0x7) << 2;
+    address |= (y & 0x3) << 5;
+    address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5;
+    address |= (ba & 3) << 8;
+    address |= (y & 0x8) << 7;
+    address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7;
+    address |= (ba & ~0x3) << 10;
+    return address;
+}
+
+static GLuint get_depth_z16(const struct radeon_renderbuffer * rrb,
+                              GLint x, GLint y)
+{
+    GLuint ba, address = 0;                   /* a[0]    = 0           */
+
+    ba = (y / 16) * (rrb->pitch >> 6) + (x / 32);
+
+    address |= (x & 0x7) << 1;                /* a[1..3] = x[0..2]     */
+    address |= (y & 0x7) << 4;                /* a[4..6] = y[0..2]     */
+    address |= (x & 0x8) << 4;                /* a[7]    = x[3]        */
+    address |= (ba & 0x3) << 8;               /* a[8..9] = ba[0..1]    */
+    address |= (y & 0x8) << 7;                /* a[10]   = y[3]        */
+    address |= ((x & 0x10) ^ (y & 0x10)) << 7;/* a[11]   = x[4] ^ y[4] */
+    address |= (ba & ~0x3) << 10;             /* a[12..] = ba[2..] */
+    return address;
+}
+#endif
+
+#if defined(RADEON_R200)
+static GLuint get_depth_z32(const struct radeon_renderbuffer * rrb,
+                                GLint x, GLint y)
+{
+    GLuint offset;
+    GLuint b;
+    offset = 0;
+    b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5));
+    offset += (b >> 1) << 12;
+    offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
+    offset += ((y >> 2) & 0x3) << 9;
+    offset += ((x >> 2) & 0x1) << 8;
+    offset += ((x >> 3) & 0x3) << 6;
+    offset += ((y >> 1) & 0x1) << 5;
+    offset += ((x >> 1) & 0x1) << 4;
+    offset += (y & 0x1) << 3;
+    offset += (x & 0x1) << 2;
+
+    return offset;
+}
+
+static GLuint get_depth_z16(const struct radeon_renderbuffer *rrb,
+                              GLint x, GLint y)
+{
+   GLuint offset;
+   GLuint b;
+
+   offset = 0;
+   b = (((y  >> 4) * (rrb->pitch >> 7) + (x >> 6)));
+   offset += (b >> 1) << 12;
+   offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
+   offset += ((y >> 2) & 0x3) << 9;
+   offset += ((x >> 3) & 0x1) << 8;
+   offset += ((x >> 4) & 0x3) << 6;
+   offset += ((x >> 2) & 0x1) << 5;
+   offset += ((y >> 1) & 0x1) << 4;
+   offset += ((x >> 1) & 0x1) << 3;
+   offset += (y & 0x1) << 2;
+   offset += (x & 0x1) << 1;
+
+   return offset;
+}
+#endif
+
+static void
+radeon_map_renderbuffer_s8z24(struct gl_renderbuffer *rb,
+                      GLuint x, GLuint y, GLuint w, GLuint h,
+                      GLbitfield mode,
+                      GLubyte **out_map,
+                      GLint *out_stride)
+{
+    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+    uint32_t *untiled_s8z24_map, *tiled_s8z24_map;
+    int ret;
+    int y_flip = (rb->Name == 0) ? -1 : 1;
+    int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
+    uint32_t pitch = w * rrb->cpp;
+
+    rrb->map_pitch = pitch;
+
+    rrb->map_buffer = malloc(w * h * 4);
+    ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
+    assert(!ret);
+    (void) ret;
+    untiled_s8z24_map = rrb->map_buffer;
+    tiled_s8z24_map = rrb->bo->ptr;
+
+    for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) {
+       for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
+           uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
+           uint32_t src_offset = get_depth_z32(rrb, x + pix_x, flipped_y);
+           uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
+           untiled_s8z24_map[dst_offset/4] = tiled_s8z24_map[src_offset/4];
+       }
+    }
+
+    radeon_bo_unmap(rrb->bo);
+                  
+    *out_map = rrb->map_buffer;
+    *out_stride = rrb->map_pitch;
+}
+
+static void
+radeon_map_renderbuffer_z16(struct gl_renderbuffer *rb,
+                           GLuint x, GLuint y, GLuint w, GLuint h,
+                           GLbitfield mode,
+                           GLubyte **out_map,
+                           GLint *out_stride)
+{
+    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+    uint16_t *untiled_z16_map, *tiled_z16_map;
+    int ret;
+    int y_flip = (rb->Name == 0) ? -1 : 1;
+    int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
+    uint32_t pitch = w * rrb->cpp;
+
+    rrb->map_pitch = pitch;
+
+    rrb->map_buffer = malloc(w * h * 2);
+    ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
+    assert(!ret);
+    (void) ret;
+
+    untiled_z16_map = rrb->map_buffer;
+    tiled_z16_map = rrb->bo->ptr;
+
+    for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) {
+       for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
+           uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
+           uint32_t src_offset = get_depth_z16(rrb, x + pix_x, flipped_y);
+           uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
+           untiled_z16_map[dst_offset/2] = tiled_z16_map[src_offset/2];
+       }
+    }
+
+    radeon_bo_unmap(rrb->bo);
+
+    *out_map = rrb->map_buffer;
+    *out_stride = rrb->map_pitch;
+}
+
+static void
+radeon_map_renderbuffer(struct gl_context *ctx,
+                      struct gl_renderbuffer *rb,
+                      GLuint x, GLuint y, GLuint w, GLuint h,
+                      GLbitfield mode,
+                      GLubyte **out_map,
+                      GLint *out_stride,
+                      bool flip_y)
+{
+   struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
+   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+   GLubyte *map;
+   GLboolean ok;
+   int stride, flip_stride;
+   int ret;
+   int src_x, src_y;
+
+   /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
+   assert((rb->Name == 0) == flip_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.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);
+   }
+
+   if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) {
+       if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT || rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT) {
+          radeon_map_renderbuffer_s8z24(rb, x, y, w, h,
+                                        mode, out_map, out_stride);
+          return;
+       }
+       if (rb->Format == MESA_FORMAT_Z_UNORM16) {
+          radeon_map_renderbuffer_z16(rb, x, y, w, h,
+                                      mode, out_map, out_stride);
+          return;
+       }
+   }
+
+   ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
+   assert(!ret);
+   (void) ret;
+
+   map = rrb->bo->ptr;
+   stride = rrb->map_pitch;
+
+   if (rb->Name == 0) {
+      y = rb->Height - 1 - y;
+      flip_stride = -stride;
+   } else {
+      flip_stride = stride;
+      map += rrb->draw_offset;
+   }
+
+   map += x * rrb->cpp;
+   map += (int)y * stride;
+
+   *out_map = map;
+   *out_stride = flip_stride;
+}
+
+static void
+radeon_unmap_renderbuffer_s8z24(struct gl_context *ctx,
+                         struct gl_renderbuffer *rb)
+{
+   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+
+   if (!rrb->map_buffer)
+     return;
+
+   if (rrb->map_mode & GL_MAP_WRITE_BIT) {
+       uint32_t *untiled_s8z24_map = rrb->map_buffer;
+       uint32_t *tiled_s8z24_map;
+       int y_flip = (rb->Name == 0) ? -1 : 1;
+       int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
+
+       radeon_bo_map(rrb->bo, 1);
+       
+       tiled_s8z24_map = rrb->bo->ptr;
+
+       for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) {
+          for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) {
+              uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias;
+              uint32_t dst_offset = get_depth_z32(rrb, rrb->map_x + pix_x, flipped_y);
+              uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
+              tiled_s8z24_map[dst_offset/4] = untiled_s8z24_map[src_offset/4];
+          }
+       }
+       radeon_bo_unmap(rrb->bo);
+   }
+   free(rrb->map_buffer);
+   rrb->map_buffer = NULL;
+}
+
+static void
+radeon_unmap_renderbuffer_z16(struct gl_context *ctx,
+                             struct gl_renderbuffer *rb)
+{
+   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+
+   if (!rrb->map_buffer)
+     return;
+
+   if (rrb->map_mode & GL_MAP_WRITE_BIT) {
+       uint16_t *untiled_z16_map = rrb->map_buffer;
+       uint16_t *tiled_z16_map;
+       int y_flip = (rb->Name == 0) ? -1 : 1;
+       int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
+
+       radeon_bo_map(rrb->bo, 1);
+       
+       tiled_z16_map = rrb->bo->ptr;
+
+       for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) {
+          for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) {
+              uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias;
+              uint32_t dst_offset = get_depth_z16(rrb, rrb->map_x + pix_x, flipped_y);
+              uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
+              tiled_z16_map[dst_offset/2] = untiled_z16_map[src_offset/2];
+          }
+       }
+       radeon_bo_unmap(rrb->bo);
+   }
+   free(rrb->map_buffer);
+   rrb->map_buffer = NULL;
+}
+
 
-  return NULL;
+static void
+radeon_unmap_renderbuffer(struct gl_context *ctx,
+                         struct gl_renderbuffer *rb)
+{
+   struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
+   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+
+   if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) {
+       if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT || rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT) {
+          radeon_unmap_renderbuffer_s8z24(ctx, rb);
+          return;
+       }
+       if (rb->Format == MESA_FORMAT_Z_UNORM16) {
+          radeon_unmap_renderbuffer_z16(ctx, rb);
+          return;
+       }
+   }
+
+   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) {
+      GLboolean ok;
+      ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0,
+                           rb->Format, rrb->map_pitch / rrb->cpp,
+                           rrb->map_w, rrb->map_h,
+                           0, 0,
+                           rrb->bo, rrb->draw_offset,
+                           rb->Format, rrb->pitch / rrb->cpp,
+                           rb->Width, rb->Height,
+                           rrb->map_x, rrb->map_y,
+                           rrb->map_w, rrb->map_h,
+                           GL_FALSE);
+      assert(ok);
+      (void) ok;
+   }
+
+   radeon_bo_unref(rrb->map_bo);
+   rrb->map_bo = NULL;
 }
 
+
 /**
  * Called via glRenderbufferStorageEXT() to set the format and allocate
  * storage for a user-created renderbuffer.
  */
 static GLboolean
-radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
+radeon_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
                                  GLenum internalFormat,
                                  GLuint width, GLuint height)
 {
   struct radeon_context *radeon = RADEON_CONTEXT(ctx);
   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
-  GLboolean software_buffer = GL_FALSE;
+  uint32_t size, pitch;
   int cpp;
 
   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
                "%s(%p, rb %p) \n",
                __func__, ctx, rb);
 
-   ASSERT(rb->Name != 0);
+   assert(rb->Name != 0);
   switch (internalFormat) {
    case GL_R3_G3_B2:
    case GL_RGB4:
    case GL_RGB5:
-      rb->Format = _dri_texformat_rgb565;
-      rb->DataType = GL_UNSIGNED_BYTE;
+      rb->Format = _radeon_texformat_rgb565;
       cpp = 2;
       break;
    case GL_RGB:
@@ -112,8 +487,7 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
    case GL_RGB10:
    case GL_RGB12:
    case GL_RGB16:
-      rb->Format = _dri_texformat_argb8888;
-      rb->DataType = GL_UNSIGNED_BYTE;
+      rb->Format = _radeon_texformat_argb8888;
       cpp = 4;
       break;
    case GL_RGBA:
@@ -124,8 +498,7 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
    case GL_RGB10_A2:
    case GL_RGBA12:
    case GL_RGBA16:
-      rb->Format = _dri_texformat_argb8888;
-      rb->DataType = GL_UNSIGNED_BYTE;
+      rb->Format = _radeon_texformat_argb8888;
       cpp = 4;
       break;
    case GL_STENCIL_INDEX:
@@ -134,26 +507,22 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
    case GL_STENCIL_INDEX8_EXT:
    case GL_STENCIL_INDEX16_EXT:
       /* alloc a depth+stencil buffer */
-      rb->Format = MESA_FORMAT_S8_Z24;
-      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
+      rb->Format = MESA_FORMAT_Z24_UNORM_S8_UINT;
       cpp = 4;
       break;
    case GL_DEPTH_COMPONENT16:
-      rb->Format = MESA_FORMAT_Z16;
-      rb->DataType = GL_UNSIGNED_SHORT;
+      rb->Format = MESA_FORMAT_Z_UNORM16;
       cpp = 2;
       break;
    case GL_DEPTH_COMPONENT:
    case GL_DEPTH_COMPONENT24:
    case GL_DEPTH_COMPONENT32:
-      rb->Format = MESA_FORMAT_X8_Z24;
-      rb->DataType = GL_UNSIGNED_INT;
+      rb->Format = MESA_FORMAT_Z24_UNORM_X8_UINT;
       cpp = 4;
       break;
    case GL_DEPTH_STENCIL_EXT:
    case GL_DEPTH24_STENCIL8_EXT:
-      rb->Format = MESA_FORMAT_S8_Z24;
-      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
+      rb->Format = MESA_FORMAT_Z24_UNORM_S8_UINT;
       cpp = 4;
       break;
    default:
@@ -169,36 +538,67 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
 
   if (rrb->bo)
     radeon_bo_unref(rrb->bo);
-  
-    
-   if (software_buffer) {
-      return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat,
-                                             width, height);
-   }
-   else {
-     uint32_t size;
-     uint32_t pitch = ((cpp * width + 63) & ~63) / cpp;
-
-     if (RADEON_DEBUG & RADEON_MEMORY)
-            fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
-                    height, pitch);
-
-     size = pitch * height * cpp;
-     rrb->pitch = pitch * cpp;
-     rrb->cpp = cpp;
-     rrb->bo = radeon_bo_open(radeon->radeonScreen->bom,
-                             0,
-                             size,
-                             0,
-                             RADEON_GEM_DOMAIN_VRAM,
-                             0);
-     rb->Width = width;
-     rb->Height = height;
-       return GL_TRUE;
-   }    
-   
+
+   pitch = ((cpp * width + 63) & ~63) / cpp;
+
+   if (RADEON_DEBUG & RADEON_MEMORY)
+      fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
+             height, pitch);
+
+   size = pitch * height * cpp;
+   rrb->pitch = pitch * cpp;
+   rrb->cpp = cpp;
+   rrb->bo = radeon_bo_open(radeon->radeonScreen->bom,
+                           0,
+                           size,
+                           0,
+                           RADEON_GEM_DOMAIN_VRAM,
+                           0);
+   rb->Width = width;
+   rb->Height = height;
+   return GL_TRUE;
 }
 
+static void
+radeon_image_target_renderbuffer_storage(struct gl_context *ctx,
+                                         struct gl_renderbuffer *rb,
+                                         void *image_handle)
+{
+   radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+   struct radeon_renderbuffer *rrb;
+   __DRIscreen *screen;
+   __DRIimage *image;
+
+   screen = radeon->radeonScreen->driScreen;
+   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
+                                             screen->loaderPrivate);
+   if (image == NULL)
+      return;
+
+   rrb = radeon_renderbuffer(rb);
+
+   if (ctx->Driver.Flush)
+      ctx->Driver.Flush(ctx); /* +r6/r7 */
+
+   if (rrb->bo)
+      radeon_bo_unref(rrb->bo);
+   rrb->bo = image->bo;
+   radeon_bo_ref(rrb->bo);
+   fprintf(stderr, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image->bo, image->bo->handle,
+           image->width, image->pitch);
+
+   rrb->cpp = image->cpp;
+   rrb->pitch = image->pitch * image->cpp;
+
+   rb->Format = image->format;
+   rb->InternalFormat = image->internal_format;
+   rb->Width = image->width;
+   rb->Height = image->height;
+   rb->Format = image->format;
+   rb->_BaseFormat = _mesa_base_fbo_format(&radeon->glCtx,
+                                           image->internal_format);
+   rb->NeedsFinishRenderTexture = GL_TRUE;
+}
 
 /**
  * Called for each hardware renderbuffer when a _window_ is resized.
@@ -206,10 +606,10 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
  * Not used for user-created renderbuffers!
  */
 static GLboolean
-radeon_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
+radeon_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
                            GLenum internalFormat, GLuint width, GLuint height)
 {
-   ASSERT(rb->Name == 0);
+   assert(rb->Name == 0);
    rb->Width = width;
    rb->Height = height;
    rb->InternalFormat = internalFormat;
@@ -221,42 +621,13 @@ radeon_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
    return GL_TRUE;
 }
 
-
-static void
-radeon_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb,
-                    GLuint width, GLuint height)
-{
-     struct radeon_framebuffer *radeon_fb = (struct radeon_framebuffer*)fb;
-   int i;
-
-  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
-               "%s(%p, fb %p) \n",
-               __func__, ctx, fb);
-
-   _mesa_resize_framebuffer(ctx, fb, width, height);
-
-   fb->Initialized = GL_TRUE; /* XXX remove someday */
-
-   if (fb->Name != 0) {
-      return;
-   }
-
-   /* Make sure all window system renderbuffers are up to date */
-   for (i = 0; i < 2; i++) {
-      struct gl_renderbuffer *rb = &radeon_fb->color_rb[i]->base;
-
-      /* only resize if size is changing */
-      if (rb && (rb->Width != width || rb->Height != height)) {
-        rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
-      }
-   }
-}
-
-
 /** Dummy function for gl_renderbuffer::AllocStorage() */
 static GLboolean
-radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
-                        GLenum internalFormat, GLuint width, GLuint height)
+radeon_nop_alloc_storage(struct gl_context * ctx,
+                        UNUSED struct gl_renderbuffer *rb,
+                        UNUSED GLenum internalFormat,
+                        UNUSED GLuint width,
+                        UNUSED GLuint height)
 {
    _mesa_problem(ctx, "radeon_op_alloc_storage should never be called.");
    return GL_FALSE;
@@ -268,9 +639,10 @@ radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
  * Not used for user-created renderbuffers.
  */
 struct radeon_renderbuffer *
-radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv)
+radeon_create_renderbuffer(mesa_format format, __DRIdrawable *driDrawPriv)
 {
     struct radeon_renderbuffer *rrb;
+    struct gl_renderbuffer *rb;
 
     rrb = CALLOC_STRUCT(radeon_renderbuffer);
 
@@ -281,80 +653,29 @@ radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv)
     if (!rrb)
        return NULL;
 
-    _mesa_init_renderbuffer(&rrb->base, 0);
-    rrb->base.ClassID = RADEON_RB_CLASS;
-
-    rrb->base.Format = format;
-
-    switch (format) {
-        case MESA_FORMAT_RGB565:
-           assert(_mesa_little_endian());
-           rrb->base.DataType = GL_UNSIGNED_BYTE;
-            rrb->base._BaseFormat = GL_RGB;
-           break;
-        case MESA_FORMAT_RGB565_REV:
-           assert(!_mesa_little_endian());
-           rrb->base.DataType = GL_UNSIGNED_BYTE;
-            rrb->base._BaseFormat = GL_RGB;
-           break;
-        case MESA_FORMAT_XRGB8888:
-           assert(_mesa_little_endian());
-           rrb->base.DataType = GL_UNSIGNED_BYTE;
-            rrb->base._BaseFormat = GL_RGB;
-           break;
-        case MESA_FORMAT_XRGB8888_REV:
-           assert(!_mesa_little_endian());
-           rrb->base.DataType = GL_UNSIGNED_BYTE;
-            rrb->base._BaseFormat = GL_RGB;
-           break;
-       case MESA_FORMAT_ARGB8888:
-           assert(_mesa_little_endian());
-           rrb->base.DataType = GL_UNSIGNED_BYTE;
-            rrb->base._BaseFormat = GL_RGBA;
-           break;
-       case MESA_FORMAT_ARGB8888_REV:
-           assert(!_mesa_little_endian());
-           rrb->base.DataType = GL_UNSIGNED_BYTE;
-            rrb->base._BaseFormat = GL_RGBA;
-           break;
-       case MESA_FORMAT_S8:
-           rrb->base.DataType = GL_UNSIGNED_BYTE;
-            rrb->base._BaseFormat = GL_STENCIL_INDEX;
-           break;
-       case MESA_FORMAT_Z16:
-           rrb->base.DataType = GL_UNSIGNED_SHORT;
-            rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
-           break;
-       case MESA_FORMAT_X8_Z24:
-           rrb->base.DataType = GL_UNSIGNED_INT;
-            rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
-           break;
-       case MESA_FORMAT_S8_Z24:
-           rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
-            rrb->base._BaseFormat = GL_DEPTH_STENCIL;
-           break;
-       default:
-           fprintf(stderr, "%s: Unknown format %s\n",
-                    __FUNCTION__, _mesa_get_format_name(format));
-           _mesa_delete_renderbuffer(&rrb->base);
-           return NULL;
-    }
+    rb = &rrb->base.Base;
+
+    _mesa_init_renderbuffer(rb, 0);
+    rb->ClassID = RADEON_RB_CLASS;
+    rb->Format = format;
+    rb->_BaseFormat = _mesa_get_format_base_format(format);
+    rb->InternalFormat = _mesa_get_format_base_format(format);
 
     rrb->dPriv = driDrawPriv;
-    rrb->base.InternalFormat = _mesa_get_format_base_format(format);
 
-    rrb->base.Delete = radeon_delete_renderbuffer;
-    rrb->base.AllocStorage = radeon_alloc_window_storage;
-    rrb->base.GetPointer = radeon_get_pointer;
+    rb->Delete = radeon_delete_renderbuffer;
+    rb->AllocStorage = radeon_alloc_window_storage;
 
     rrb->bo = NULL;
     return rrb;
 }
 
 static struct gl_renderbuffer *
-radeon_new_renderbuffer(GLcontext * ctx, GLuint name)
+radeon_new_renderbuffer(struct gl_context * ctx, GLuint name)
 {
   struct radeon_renderbuffer *rrb;
+  struct gl_renderbuffer *rb;
+
 
   rrb = CALLOC_STRUCT(radeon_renderbuffer);
 
@@ -365,24 +686,24 @@ radeon_new_renderbuffer(GLcontext * ctx, GLuint name)
   if (!rrb)
     return NULL;
 
-  _mesa_init_renderbuffer(&rrb->base, name);
-  rrb->base.ClassID = RADEON_RB_CLASS;
+  rb = &rrb->base.Base;
 
-  rrb->base.Delete = radeon_delete_renderbuffer;
-  rrb->base.AllocStorage = radeon_alloc_renderbuffer_storage;
-  rrb->base.GetPointer = radeon_get_pointer;
+  _mesa_init_renderbuffer(rb, name);
+  rb->ClassID = RADEON_RB_CLASS;
+  rb->Delete = radeon_delete_renderbuffer;
+  rb->AllocStorage = radeon_alloc_renderbuffer_storage;
 
-  return &rrb->base;
+  return rb;
 }
 
 static void
-radeon_bind_framebuffer(GLcontext * ctx, GLenum target,
+radeon_bind_framebuffer(struct gl_context * ctx, GLenum target,
                        struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
 {
   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
                "%s(%p, fb %p, target %s) \n",
                __func__, ctx, fb,
-               _mesa_lookup_enum_by_nr(target));
+               _mesa_enum_to_string(target));
 
    if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
       radeon_draw_buffer(ctx, fb);
@@ -393,7 +714,7 @@ radeon_bind_framebuffer(GLcontext * ctx, GLenum target,
 }
 
 static void
-radeon_framebuffer_renderbuffer(GLcontext * ctx,
+radeon_framebuffer_renderbuffer(struct gl_context * ctx,
                                struct gl_framebuffer *fb,
                                GLenum attachment, struct gl_renderbuffer *rb)
 {
@@ -405,96 +726,41 @@ radeon_framebuffer_renderbuffer(GLcontext * ctx,
                "%s(%p, fb %p, rb %p) \n",
                __func__, ctx, fb, rb);
 
-   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
+   _mesa_FramebufferRenderbuffer_sw(ctx, fb, attachment, rb);
    radeon_draw_buffer(ctx, fb);
 }
 
 static GLboolean
-radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb, 
+radeon_update_wrapper(struct gl_context *ctx, struct radeon_renderbuffer *rrb, 
                     struct gl_texture_image *texImage)
 {
+       struct gl_renderbuffer *rb = &rrb->base.Base;
+
        radeon_print(RADEON_TEXTURE, RADEON_TRACE,
                "%s(%p, rrb %p, texImage %p, texFormat %s) \n",
                __func__, ctx, rrb, texImage, _mesa_get_format_name(texImage->TexFormat));
 
-       switch (texImage->TexFormat) {
-               case MESA_FORMAT_RGBA8888:
-               case MESA_FORMAT_RGBA8888_REV:
-               case MESA_FORMAT_ARGB8888:
-               case MESA_FORMAT_ARGB8888_REV:
-               case MESA_FORMAT_XRGB8888:
-               case MESA_FORMAT_XRGB8888_REV:
-               case MESA_FORMAT_RGB565:
-               case MESA_FORMAT_RGB565_REV:
-               case MESA_FORMAT_RGBA5551:
-               case MESA_FORMAT_ARGB1555:
-               case MESA_FORMAT_ARGB1555_REV:
-               case MESA_FORMAT_ARGB4444:
-               case MESA_FORMAT_ARGB4444_REV:
-                       rrb->base.DataType = GL_UNSIGNED_BYTE;
-                       break;
-               case MESA_FORMAT_Z16:
-                       rrb->base.DataType = GL_UNSIGNED_SHORT;
-                       break;
-               case MESA_FORMAT_X8_Z24:
-                       rrb->base.DataType = GL_UNSIGNED_INT;
-                       break;
-               case MESA_FORMAT_S8_Z24:
-                       rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
-                       break;
-       }
-               
        rrb->cpp = _mesa_get_format_bytes(texImage->TexFormat);
        rrb->pitch = texImage->Width * rrb->cpp;
-       rrb->base.Format = texImage->TexFormat;
-       rrb->base.InternalFormat = texImage->InternalFormat;
-       rrb->base._BaseFormat = _mesa_base_fbo_format(ctx, rrb->base.InternalFormat);
-       rrb->base.Width = texImage->Width;
-       rrb->base.Height = texImage->Height;
-       rrb->base.Delete = radeon_delete_renderbuffer;
-       rrb->base.AllocStorage = radeon_nop_alloc_storage;
+       rb->Format = texImage->TexFormat;
+       rb->InternalFormat = texImage->InternalFormat;
+       rb->_BaseFormat = _mesa_get_format_base_format(rb->Format);
+       rb->Width = texImage->Width;
+       rb->Height = texImage->Height;
+       rb->Delete = radeon_delete_renderbuffer;
+       rb->AllocStorage = radeon_nop_alloc_storage;
 
        return GL_TRUE;
 }
 
-
-static struct radeon_renderbuffer *
-radeon_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage)
-{
-  const GLuint name = ~0;   /* not significant, but distinct for debugging */
-  struct radeon_renderbuffer *rrb;
-
-   /* make an radeon_renderbuffer to wrap the texture image */
-   rrb = CALLOC_STRUCT(radeon_renderbuffer);
-
-   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
-               "%s(%p, rrb %p, texImage %p) \n",
-               __func__, ctx, rrb, texImage);
-
-   if (!rrb) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
-      return NULL;
-   }
-
-   _mesa_init_renderbuffer(&rrb->base, name);
-   rrb->base.ClassID = RADEON_RB_CLASS;
-
-   if (!radeon_update_wrapper(ctx, rrb, texImage)) {
-      free(rrb);
-      return NULL;
-   }
-
-   return rrb;
-  
-}
 static void
-radeon_render_texture(GLcontext * ctx,
+radeon_render_texture(struct gl_context * ctx,
                      struct gl_framebuffer *fb,
                      struct gl_renderbuffer_attachment *att)
 {
-   struct gl_texture_image *newImage
-      = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
-   struct radeon_renderbuffer *rrb = radeon_renderbuffer(att->Renderbuffer);
+   struct gl_renderbuffer *rb = att->Renderbuffer;
+   struct gl_texture_image *newImage = rb->TexImage;
+   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    radeon_texture_image *radeon_image;
    GLuint imageOffset;
 
@@ -504,42 +770,27 @@ radeon_render_texture(GLcontext * ctx,
 
    (void) fb;
 
-   ASSERT(newImage);
+   assert(newImage);
+
+   radeon_image = (radeon_texture_image *)newImage;
 
-   if (newImage->Border != 0) {
-      /* Fallback on drawing to a texture with a border, which won't have a
-       * miptree.
+   if (!radeon_image->mt) {
+      /* Fallback on drawing to a texture without a miptree.
        */
-      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
-      _mesa_render_texture(ctx, fb, att);
+      _swrast_render_texture(ctx, fb, att);
       return;
    }
-   else if (!rrb) {
-      rrb = radeon_wrap_texture(ctx, newImage);
-      if (rrb) {
-         /* bind the wrapper to the attachment point */
-         _mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base);
-      }
-      else {
-         /* fallback to software rendering */
-         _mesa_render_texture(ctx, fb, att);
-         return;
-      }
-   }
 
    if (!radeon_update_wrapper(ctx, rrb, newImage)) {
-       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
-       _mesa_render_texture(ctx, fb, att);
+       _swrast_render_texture(ctx, fb, att);
        return;
    }
 
-   DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
-       _glthread_GetID(),
+   DBG("Begin render texture tex=%u w=%d h=%d refcount=%d\n",
        att->Texture->Name, newImage->Width, newImage->Height,
-       rrb->base.RefCount);
+       rb->RefCount);
 
    /* point the renderbufer's region to the texture image region */
-   radeon_image = (radeon_texture_image *)newImage;
    if (rrb->bo != radeon_image->mt->bo) {
       if (rrb->bo)
        radeon_bo_unref(rrb->bo);
@@ -562,22 +813,29 @@ radeon_render_texture(GLcontext * 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);
 }
 
 static void
-radeon_finish_render_texture(GLcontext * ctx,
-                            struct gl_renderbuffer_attachment *att)
+radeon_finish_render_texture(struct gl_context *ctx, struct gl_renderbuffer *rb)
 {
+    struct gl_texture_image *image = rb->TexImage;
+    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(GLcontext *ctx, struct gl_framebuffer *fb)
+radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
 {
        radeonContextPtr radeon = RADEON_CONTEXT(ctx);
-       gl_format mesa_format;
+       mesa_format mesa_format;
        int i;
 
        for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
@@ -591,7 +849,7 @@ radeon_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
                }
 
                if (att->Type == GL_TEXTURE) {
-                       mesa_format = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->TexFormat;
+                       mesa_format = att->Renderbuffer->TexImage->TexFormat;
                } else {
                        /* All renderbuffer formats are renderable, but not sampable */
                        continue;
@@ -601,7 +859,7 @@ radeon_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
                        fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
                        radeon_print(RADEON_TEXTURE, RADEON_TRACE,
                                                "%s: HW doesn't support format %s as output format of attachment %d\n",
-                                               __FUNCTION__, _mesa_get_format_name(mesa_format), i);
+                                               __func__, _mesa_get_format_name(mesa_format), i);
                        return;
                }
        }
@@ -609,15 +867,17 @@ radeon_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
 
 void radeon_fbo_init(struct radeon_context *radeon)
 {
-  radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer;
-  radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer;
-  radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer;
-  radeon->glCtx->Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer;
-  radeon->glCtx->Driver.RenderTexture = radeon_render_texture;
-  radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture;
-  radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers;
-  radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer;
-  radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
+  radeon->glCtx.Driver.NewRenderbuffer = radeon_new_renderbuffer;
+  radeon->glCtx.Driver.MapRenderbuffer = radeon_map_renderbuffer;
+  radeon->glCtx.Driver.UnmapRenderbuffer = radeon_unmap_renderbuffer;
+  radeon->glCtx.Driver.BindFramebuffer = radeon_bind_framebuffer;
+  radeon->glCtx.Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer;
+  radeon->glCtx.Driver.RenderTexture = radeon_render_texture;
+  radeon->glCtx.Driver.FinishRenderTexture = radeon_finish_render_texture;
+  radeon->glCtx.Driver.ValidateFramebuffer = radeon_validate_framebuffer;
+  radeon->glCtx.Driver.BlitFramebuffer = _mesa_meta_and_swrast_BlitFramebuffer;
+  radeon->glCtx.Driver.EGLImageTargetRenderbufferStorage =
+         radeon_image_target_renderbuffer_storage;
 }