Home | History | Annotate | Download | only in radeon
      1 /**************************************************************************
      2  *
      3  * Copyright 2008 Red Hat Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 
     29 #include "main/imports.h"
     30 #include "main/macros.h"
     31 #include "main/mfeatures.h"
     32 #include "main/mtypes.h"
     33 #include "main/enums.h"
     34 #include "main/fbobject.h"
     35 #include "main/framebuffer.h"
     36 #include "main/renderbuffer.h"
     37 #include "main/context.h"
     38 #include "swrast/swrast.h"
     39 #include "drivers/common/meta.h"
     40 
     41 #include "radeon_common.h"
     42 #include "radeon_mipmap_tree.h"
     43 
     44 #define FILE_DEBUG_FLAG RADEON_TEXTURE
     45 #define DBG(...) do {                                           \
     46         if (RADEON_DEBUG & FILE_DEBUG_FLAG)                      \
     47                 printf(__VA_ARGS__);                      \
     48 } while(0)
     49 
     50 static struct gl_framebuffer *
     51 radeon_new_framebuffer(struct gl_context *ctx, GLuint name)
     52 {
     53   return _mesa_new_framebuffer(ctx, name);
     54 }
     55 
     56 static void
     57 radeon_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
     58 {
     59   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
     60 
     61   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
     62 		"%s(rb %p, rrb %p) \n",
     63 		__func__, rb, rrb);
     64 
     65   ASSERT(rrb);
     66 
     67   if (rrb && rrb->bo) {
     68     radeon_bo_unref(rrb->bo);
     69   }
     70   _mesa_delete_renderbuffer(ctx, rb);
     71 }
     72 
     73 #if defined(RADEON_R100)
     74 static GLuint get_depth_z32(const struct radeon_renderbuffer * rrb,
     75 			       GLint x, GLint y)
     76 {
     77     GLuint ba, address = 0;
     78 
     79     ba = (y >> 4) * (rrb->pitch >> 6) + (x >> 4);
     80 
     81     address |= (x & 0x7) << 2;
     82     address |= (y & 0x3) << 5;
     83     address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5;
     84     address |= (ba & 3) << 8;
     85     address |= (y & 0x8) << 7;
     86     address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7;
     87     address |= (ba & ~0x3) << 10;
     88     return address;
     89 }
     90 
     91 static GLuint get_depth_z16(const struct radeon_renderbuffer * rrb,
     92 			       GLint x, GLint y)
     93 {
     94     GLuint ba, address = 0;                   /* a[0]    = 0           */
     95 
     96     ba = (y / 16) * (rrb->pitch >> 6) + (x / 32);
     97 
     98     address |= (x & 0x7) << 1;                /* a[1..3] = x[0..2]     */
     99     address |= (y & 0x7) << 4;                /* a[4..6] = y[0..2]     */
    100     address |= (x & 0x8) << 4;                /* a[7]    = x[3]        */
    101     address |= (ba & 0x3) << 8;               /* a[8..9] = ba[0..1]    */
    102     address |= (y & 0x8) << 7;                /* a[10]   = y[3]        */
    103     address |= ((x & 0x10) ^ (y & 0x10)) << 7;/* a[11]   = x[4] ^ y[4] */
    104     address |= (ba & ~0x3) << 10;             /* a[12..] = ba[2..] */
    105     return address;
    106 }
    107 #endif
    108 
    109 #if defined(RADEON_R200)
    110 static GLuint get_depth_z32(const struct radeon_renderbuffer * rrb,
    111 				 GLint x, GLint y)
    112 {
    113     GLuint offset;
    114     GLuint b;
    115     offset = 0;
    116     b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5));
    117     offset += (b >> 1) << 12;
    118     offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
    119     offset += ((y >> 2) & 0x3) << 9;
    120     offset += ((x >> 2) & 0x1) << 8;
    121     offset += ((x >> 3) & 0x3) << 6;
    122     offset += ((y >> 1) & 0x1) << 5;
    123     offset += ((x >> 1) & 0x1) << 4;
    124     offset += (y & 0x1) << 3;
    125     offset += (x & 0x1) << 2;
    126 
    127     return offset;
    128 }
    129 
    130 static GLuint get_depth_z16(const struct radeon_renderbuffer *rrb,
    131 			       GLint x, GLint y)
    132 {
    133    GLuint offset;
    134    GLuint b;
    135 
    136    offset = 0;
    137    b = (((y  >> 4) * (rrb->pitch >> 7) + (x >> 6)));
    138    offset += (b >> 1) << 12;
    139    offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
    140    offset += ((y >> 2) & 0x3) << 9;
    141    offset += ((x >> 3) & 0x1) << 8;
    142    offset += ((x >> 4) & 0x3) << 6;
    143    offset += ((x >> 2) & 0x1) << 5;
    144    offset += ((y >> 1) & 0x1) << 4;
    145    offset += ((x >> 1) & 0x1) << 3;
    146    offset += (y & 0x1) << 2;
    147    offset += (x & 0x1) << 1;
    148 
    149    return offset;
    150 }
    151 #endif
    152 
    153 static void
    154 radeon_map_renderbuffer_s8z24(struct gl_context *ctx,
    155 		       struct gl_renderbuffer *rb,
    156 		       GLuint x, GLuint y, GLuint w, GLuint h,
    157 		       GLbitfield mode,
    158 		       GLubyte **out_map,
    159 		       GLint *out_stride)
    160 {
    161     struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    162     uint32_t *untiled_s8z24_map, *tiled_s8z24_map;
    163     int ret;
    164     int y_flip = (rb->Name == 0) ? -1 : 1;
    165     int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
    166     uint32_t pitch = w * rrb->cpp;
    167 
    168     rrb->map_pitch = pitch;
    169 
    170     rrb->map_buffer = malloc(w * h * 4);
    171     ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
    172     assert(!ret);
    173     untiled_s8z24_map = rrb->map_buffer;
    174     tiled_s8z24_map = rrb->bo->ptr;
    175 
    176     for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) {
    177 	for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
    178 	    uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
    179 	    uint32_t src_offset = get_depth_z32(rrb, x + pix_x, flipped_y);
    180 	    uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
    181 	    untiled_s8z24_map[dst_offset/4] = tiled_s8z24_map[src_offset/4];
    182 	}
    183     }
    184 
    185     radeon_bo_unmap(rrb->bo);
    186 
    187     *out_map = rrb->map_buffer;
    188     *out_stride = rrb->map_pitch;
    189 }
    190 
    191 static void
    192 radeon_map_renderbuffer_z16(struct gl_context *ctx,
    193 			    struct gl_renderbuffer *rb,
    194 			    GLuint x, GLuint y, GLuint w, GLuint h,
    195 			    GLbitfield mode,
    196 			    GLubyte **out_map,
    197 			    GLint *out_stride)
    198 {
    199     struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    200     uint16_t *untiled_z16_map, *tiled_z16_map;
    201     int ret;
    202     int y_flip = (rb->Name == 0) ? -1 : 1;
    203     int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
    204     uint32_t pitch = w * rrb->cpp;
    205 
    206     rrb->map_pitch = pitch;
    207 
    208     rrb->map_buffer = malloc(w * h * 2);
    209     ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
    210     assert(!ret);
    211 
    212     untiled_z16_map = rrb->map_buffer;
    213     tiled_z16_map = rrb->bo->ptr;
    214 
    215     for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) {
    216 	for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
    217 	    uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
    218 	    uint32_t src_offset = get_depth_z16(rrb, x + pix_x, flipped_y);
    219 	    uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
    220 	    untiled_z16_map[dst_offset/2] = tiled_z16_map[src_offset/2];
    221 	}
    222     }
    223 
    224     radeon_bo_unmap(rrb->bo);
    225 
    226     *out_map = rrb->map_buffer;
    227     *out_stride = rrb->map_pitch;
    228 }
    229 
    230 static void
    231 radeon_map_renderbuffer(struct gl_context *ctx,
    232 		       struct gl_renderbuffer *rb,
    233 		       GLuint x, GLuint y, GLuint w, GLuint h,
    234 		       GLbitfield mode,
    235 		       GLubyte **out_map,
    236 		       GLint *out_stride)
    237 {
    238    struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
    239    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    240    GLubyte *map;
    241    GLboolean ok;
    242    int stride, flip_stride;
    243    int ret;
    244    int src_x, src_y;
    245 
    246    if (!rrb || !rrb->bo) {
    247 	   *out_map = NULL;
    248 	   *out_stride = 0;
    249 	   return;
    250    }
    251 
    252    rrb->map_mode = mode;
    253    rrb->map_x = x;
    254    rrb->map_y = y;
    255    rrb->map_w = w;
    256    rrb->map_h = h;
    257    rrb->map_pitch = rrb->pitch;
    258 
    259    ok = rmesa->vtbl.check_blit(rb->Format, rrb->pitch / rrb->cpp);
    260    if (ok) {
    261        if (rb->Name) {
    262 	   src_x = x;
    263 	   src_y = y;
    264        } else {
    265 	   src_x = x;
    266 	   src_y = rrb->base.Base.Height - y - h;
    267        }
    268 
    269        /* Make a temporary buffer and blit the current contents of the renderbuffer
    270 	* out to it.  This gives us linear access to the buffer, instead of having
    271 	* to do detiling in software.
    272 	*/
    273 
    274        rrb->map_pitch = rrb->pitch;
    275 
    276        assert(!rrb->map_bo);
    277        rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0,
    278 				    rrb->map_pitch * h, 4,
    279 				    RADEON_GEM_DOMAIN_GTT, 0);
    280 
    281        ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
    282 			     rb->Format, rrb->pitch / rrb->cpp,
    283 			     rb->Width, rb->Height,
    284 			     src_x, src_y,
    285 			     rrb->map_bo, 0,
    286 			     rb->Format, rrb->map_pitch / rrb->cpp,
    287 			     w, h,
    288 			     0, 0,
    289 			     w, h,
    290 			     GL_FALSE);
    291        assert(ok);
    292 
    293        ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
    294        assert(!ret);
    295 
    296        map = rrb->map_bo->ptr;
    297 
    298        if (rb->Name) {
    299 	   *out_map = map;
    300 	   *out_stride = rrb->map_pitch;
    301        } else {
    302 	   *out_map = map + (h - 1) * rrb->map_pitch;
    303 	   *out_stride = -rrb->map_pitch;
    304        }
    305        return;
    306    }
    307 
    308    /* sw fallback flush stuff */
    309    if (radeon_bo_is_referenced_by_cs(rrb->bo, rmesa->cmdbuf.cs)) {
    310       radeon_firevertices(rmesa);
    311    }
    312 
    313    if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) {
    314        if (rb->Format == MESA_FORMAT_S8_Z24 || rb->Format == MESA_FORMAT_X8_Z24) {
    315 	   radeon_map_renderbuffer_s8z24(ctx, rb, x, y, w, h,
    316 					 mode, out_map, out_stride);
    317 	   return;
    318        }
    319        if (rb->Format == MESA_FORMAT_Z16) {
    320 	   radeon_map_renderbuffer_z16(ctx, rb, x, y, w, h,
    321 				       mode, out_map, out_stride);
    322 	   return;
    323        }
    324    }
    325 
    326    ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
    327    assert(!ret);
    328 
    329    map = rrb->bo->ptr;
    330    stride = rrb->map_pitch;
    331 
    332    if (rb->Name == 0) {
    333       y = rb->Height - 1 - y;
    334       flip_stride = -stride;
    335    } else {
    336       flip_stride = stride;
    337       map += rrb->draw_offset;
    338    }
    339 
    340    map += x * rrb->cpp;
    341    map += (int)y * stride;
    342 
    343    *out_map = map;
    344    *out_stride = flip_stride;
    345 }
    346 
    347 static void
    348 radeon_unmap_renderbuffer_s8z24(struct gl_context *ctx,
    349 			  struct gl_renderbuffer *rb)
    350 {
    351    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    352 
    353    if (!rrb->map_buffer)
    354      return;
    355 
    356    if (rrb->map_mode & GL_MAP_WRITE_BIT) {
    357        uint32_t *untiled_s8z24_map = rrb->map_buffer;
    358        uint32_t *tiled_s8z24_map;
    359        int y_flip = (rb->Name == 0) ? -1 : 1;
    360        int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
    361 
    362        radeon_bo_map(rrb->bo, 1);
    363 
    364        tiled_s8z24_map = rrb->bo->ptr;
    365 
    366        for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) {
    367 	   for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) {
    368 	       uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias;
    369 	       uint32_t dst_offset = get_depth_z32(rrb, rrb->map_x + pix_x, flipped_y);
    370 	       uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
    371 	       tiled_s8z24_map[dst_offset/4] = untiled_s8z24_map[src_offset/4];
    372 	   }
    373        }
    374        radeon_bo_unmap(rrb->bo);
    375    }
    376    free(rrb->map_buffer);
    377    rrb->map_buffer = NULL;
    378 }
    379 
    380 static void
    381 radeon_unmap_renderbuffer_z16(struct gl_context *ctx,
    382 			      struct gl_renderbuffer *rb)
    383 {
    384    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    385 
    386    if (!rrb->map_buffer)
    387      return;
    388 
    389    if (rrb->map_mode & GL_MAP_WRITE_BIT) {
    390        uint16_t *untiled_z16_map = rrb->map_buffer;
    391        uint16_t *tiled_z16_map;
    392        int y_flip = (rb->Name == 0) ? -1 : 1;
    393        int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
    394 
    395        radeon_bo_map(rrb->bo, 1);
    396 
    397        tiled_z16_map = rrb->bo->ptr;
    398 
    399        for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) {
    400 	   for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) {
    401 	       uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias;
    402 	       uint32_t dst_offset = get_depth_z16(rrb, rrb->map_x + pix_x, flipped_y);
    403 	       uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
    404 	       tiled_z16_map[dst_offset/2] = untiled_z16_map[src_offset/2];
    405 	   }
    406        }
    407        radeon_bo_unmap(rrb->bo);
    408    }
    409    free(rrb->map_buffer);
    410    rrb->map_buffer = NULL;
    411 }
    412 
    413 
    414 static void
    415 radeon_unmap_renderbuffer(struct gl_context *ctx,
    416 			  struct gl_renderbuffer *rb)
    417 {
    418    struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
    419    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    420    GLboolean ok;
    421 
    422    if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) {
    423        if (rb->Format == MESA_FORMAT_S8_Z24 || rb->Format == MESA_FORMAT_X8_Z24) {
    424 	   radeon_unmap_renderbuffer_s8z24(ctx, rb);
    425 	   return;
    426        }
    427        if (rb->Format == MESA_FORMAT_Z16) {
    428 	   radeon_unmap_renderbuffer_z16(ctx, rb);
    429 	   return;
    430        }
    431    }
    432 
    433    if (!rrb->map_bo) {
    434 	   if (rrb->bo)
    435 		   radeon_bo_unmap(rrb->bo);
    436 	   return;
    437    }
    438 
    439    radeon_bo_unmap(rrb->map_bo);
    440 
    441    if (rrb->map_mode & GL_MAP_WRITE_BIT) {
    442       ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0,
    443 			    rb->Format, rrb->map_pitch / rrb->cpp,
    444 			    rrb->map_w, rrb->map_h,
    445 			    0, 0,
    446 			    rrb->bo, rrb->draw_offset,
    447 			    rb->Format, rrb->pitch / rrb->cpp,
    448 			    rb->Width, rb->Height,
    449 			    rrb->map_x, rrb->map_y,
    450 			    rrb->map_w, rrb->map_h,
    451 			    GL_FALSE);
    452       assert(ok);
    453    }
    454 
    455    radeon_bo_unref(rrb->map_bo);
    456    rrb->map_bo = NULL;
    457 }
    458 
    459 
    460 /**
    461  * Called via glRenderbufferStorageEXT() to set the format and allocate
    462  * storage for a user-created renderbuffer.
    463  */
    464 static GLboolean
    465 radeon_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
    466                                  GLenum internalFormat,
    467                                  GLuint width, GLuint height)
    468 {
    469   struct radeon_context *radeon = RADEON_CONTEXT(ctx);
    470   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
    471   uint32_t size, pitch;
    472   int cpp;
    473 
    474   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    475 		"%s(%p, rb %p) \n",
    476 		__func__, ctx, rb);
    477 
    478    ASSERT(rb->Name != 0);
    479   switch (internalFormat) {
    480    case GL_R3_G3_B2:
    481    case GL_RGB4:
    482    case GL_RGB5:
    483       rb->Format = _radeon_texformat_rgb565;
    484       cpp = 2;
    485       break;
    486    case GL_RGB:
    487    case GL_RGB8:
    488    case GL_RGB10:
    489    case GL_RGB12:
    490    case GL_RGB16:
    491       rb->Format = _radeon_texformat_argb8888;
    492       cpp = 4;
    493       break;
    494    case GL_RGBA:
    495    case GL_RGBA2:
    496    case GL_RGBA4:
    497    case GL_RGB5_A1:
    498    case GL_RGBA8:
    499    case GL_RGB10_A2:
    500    case GL_RGBA12:
    501    case GL_RGBA16:
    502       rb->Format = _radeon_texformat_argb8888;
    503       cpp = 4;
    504       break;
    505    case GL_STENCIL_INDEX:
    506    case GL_STENCIL_INDEX1_EXT:
    507    case GL_STENCIL_INDEX4_EXT:
    508    case GL_STENCIL_INDEX8_EXT:
    509    case GL_STENCIL_INDEX16_EXT:
    510       /* alloc a depth+stencil buffer */
    511       rb->Format = MESA_FORMAT_S8_Z24;
    512       cpp = 4;
    513       break;
    514    case GL_DEPTH_COMPONENT16:
    515       rb->Format = MESA_FORMAT_Z16;
    516       cpp = 2;
    517       break;
    518    case GL_DEPTH_COMPONENT:
    519    case GL_DEPTH_COMPONENT24:
    520    case GL_DEPTH_COMPONENT32:
    521       rb->Format = MESA_FORMAT_X8_Z24;
    522       cpp = 4;
    523       break;
    524    case GL_DEPTH_STENCIL_EXT:
    525    case GL_DEPTH24_STENCIL8_EXT:
    526       rb->Format = MESA_FORMAT_S8_Z24;
    527       cpp = 4;
    528       break;
    529    default:
    530       _mesa_problem(ctx,
    531                     "Unexpected format in radeon_alloc_renderbuffer_storage");
    532       return GL_FALSE;
    533    }
    534 
    535   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
    536 
    537   if (ctx->Driver.Flush)
    538 	  ctx->Driver.Flush(ctx); /* +r6/r7 */
    539 
    540   if (rrb->bo)
    541     radeon_bo_unref(rrb->bo);
    542 
    543    pitch = ((cpp * width + 63) & ~63) / cpp;
    544 
    545    if (RADEON_DEBUG & RADEON_MEMORY)
    546       fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
    547 	      height, pitch);
    548 
    549    size = pitch * height * cpp;
    550    rrb->pitch = pitch * cpp;
    551    rrb->cpp = cpp;
    552    rrb->bo = radeon_bo_open(radeon->radeonScreen->bom,
    553 			    0,
    554 			    size,
    555 			    0,
    556 			    RADEON_GEM_DOMAIN_VRAM,
    557 			    0);
    558    rb->Width = width;
    559    rb->Height = height;
    560    return GL_TRUE;
    561 }
    562 
    563 #if FEATURE_OES_EGL_image
    564 static void
    565 radeon_image_target_renderbuffer_storage(struct gl_context *ctx,
    566                                          struct gl_renderbuffer *rb,
    567                                          void *image_handle)
    568 {
    569    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
    570    struct radeon_renderbuffer *rrb;
    571    __DRIscreen *screen;
    572    __DRIimage *image;
    573 
    574    screen = radeon->radeonScreen->driScreen;
    575    image = screen->dri2.image->lookupEGLImage(screen, image_handle,
    576 					      screen->loaderPrivate);
    577    if (image == NULL)
    578       return;
    579 
    580    rrb = radeon_renderbuffer(rb);
    581 
    582    if (ctx->Driver.Flush)
    583       ctx->Driver.Flush(ctx); /* +r6/r7 */
    584 
    585    if (rrb->bo)
    586       radeon_bo_unref(rrb->bo);
    587    rrb->bo = image->bo;
    588    radeon_bo_ref(rrb->bo);
    589    fprintf(stderr, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image->bo, image->bo->handle,
    590            image->width, image->pitch);
    591 
    592    rrb->cpp = image->cpp;
    593    rrb->pitch = image->pitch * image->cpp;
    594 
    595    rb->Format = image->format;
    596    rb->InternalFormat = image->internal_format;
    597    rb->Width = image->width;
    598    rb->Height = image->height;
    599    rb->Format = image->format;
    600    rb->_BaseFormat = _mesa_base_fbo_format(radeon->glCtx,
    601                                            image->internal_format);
    602 }
    603 #endif
    604 
    605 /**
    606  * Called for each hardware renderbuffer when a _window_ is resized.
    607  * Just update fields.
    608  * Not used for user-created renderbuffers!
    609  */
    610 static GLboolean
    611 radeon_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
    612                            GLenum internalFormat, GLuint width, GLuint height)
    613 {
    614    ASSERT(rb->Name == 0);
    615    rb->Width = width;
    616    rb->Height = height;
    617    rb->InternalFormat = internalFormat;
    618   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    619 		"%s(%p, rb %p) \n",
    620 		__func__, ctx, rb);
    621 
    622 
    623    return GL_TRUE;
    624 }
    625 
    626 
    627 static void
    628 radeon_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
    629 		     GLuint width, GLuint height)
    630 {
    631      struct radeon_framebuffer *radeon_fb = (struct radeon_framebuffer*)fb;
    632    int i;
    633 
    634   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    635 		"%s(%p, fb %p) \n",
    636 		__func__, ctx, fb);
    637 
    638    _mesa_resize_framebuffer(ctx, fb, width, height);
    639 
    640    fb->Initialized = GL_TRUE; /* XXX remove someday */
    641 
    642    if (fb->Name != 0) {
    643       return;
    644    }
    645 
    646    /* Make sure all window system renderbuffers are up to date */
    647    for (i = 0; i < 2; i++) {
    648       struct gl_renderbuffer *rb = &radeon_fb->color_rb[i]->base.Base;
    649 
    650       /* only resize if size is changing */
    651       if (rb && (rb->Width != width || rb->Height != height)) {
    652 	 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
    653       }
    654    }
    655 }
    656 
    657 
    658 /** Dummy function for gl_renderbuffer::AllocStorage() */
    659 static GLboolean
    660 radeon_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
    661 			 GLenum internalFormat, GLuint width, GLuint height)
    662 {
    663    _mesa_problem(ctx, "radeon_op_alloc_storage should never be called.");
    664    return GL_FALSE;
    665 }
    666 
    667 
    668 /**
    669  * Create a renderbuffer for a window's color, depth and/or stencil buffer.
    670  * Not used for user-created renderbuffers.
    671  */
    672 struct radeon_renderbuffer *
    673 radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv)
    674 {
    675     struct radeon_renderbuffer *rrb;
    676     struct gl_renderbuffer *rb;
    677 
    678     rrb = CALLOC_STRUCT(radeon_renderbuffer);
    679 
    680     radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    681 		"%s( rrb %p ) \n",
    682 		__func__, rrb);
    683 
    684     if (!rrb)
    685 	return NULL;
    686 
    687     rb = &rrb->base.Base;
    688 
    689     _mesa_init_renderbuffer(rb, 0);
    690     rb->ClassID = RADEON_RB_CLASS;
    691     rb->Format = format;
    692     rb->_BaseFormat = _mesa_get_format_base_format(format);
    693     rb->InternalFormat = _mesa_get_format_base_format(format);
    694 
    695     rrb->dPriv = driDrawPriv;
    696 
    697     rb->Delete = radeon_delete_renderbuffer;
    698     rb->AllocStorage = radeon_alloc_window_storage;
    699 
    700     rrb->bo = NULL;
    701     return rrb;
    702 }
    703 
    704 static struct gl_renderbuffer *
    705 radeon_new_renderbuffer(struct gl_context * ctx, GLuint name)
    706 {
    707   struct radeon_renderbuffer *rrb;
    708   struct gl_renderbuffer *rb;
    709 
    710 
    711   rrb = CALLOC_STRUCT(radeon_renderbuffer);
    712 
    713   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    714 		"%s(%p, rrb %p) \n",
    715 		__func__, ctx, rrb);
    716 
    717   if (!rrb)
    718     return NULL;
    719 
    720   rb = &rrb->base.Base;
    721 
    722   _mesa_init_renderbuffer(rb, name);
    723   rb->ClassID = RADEON_RB_CLASS;
    724   rb->Delete = radeon_delete_renderbuffer;
    725   rb->AllocStorage = radeon_alloc_renderbuffer_storage;
    726 
    727   return rb;
    728 }
    729 
    730 static void
    731 radeon_bind_framebuffer(struct gl_context * ctx, GLenum target,
    732                        struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
    733 {
    734   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    735 		"%s(%p, fb %p, target %s) \n",
    736 		__func__, ctx, fb,
    737 		_mesa_lookup_enum_by_nr(target));
    738 
    739    if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
    740       radeon_draw_buffer(ctx, fb);
    741    }
    742    else {
    743       /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
    744    }
    745 }
    746 
    747 static void
    748 radeon_framebuffer_renderbuffer(struct gl_context * ctx,
    749                                struct gl_framebuffer *fb,
    750                                GLenum attachment, struct gl_renderbuffer *rb)
    751 {
    752 
    753 	if (ctx->Driver.Flush)
    754 		ctx->Driver.Flush(ctx); /* +r6/r7 */
    755 
    756 	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    757 		"%s(%p, fb %p, rb %p) \n",
    758 		__func__, ctx, fb, rb);
    759 
    760    _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
    761    radeon_draw_buffer(ctx, fb);
    762 }
    763 
    764 static GLboolean
    765 radeon_update_wrapper(struct gl_context *ctx, struct radeon_renderbuffer *rrb,
    766 		     struct gl_texture_image *texImage)
    767 {
    768 	struct gl_renderbuffer *rb = &rrb->base.Base;
    769 
    770 	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    771 		"%s(%p, rrb %p, texImage %p, texFormat %s) \n",
    772 		__func__, ctx, rrb, texImage, _mesa_get_format_name(texImage->TexFormat));
    773 
    774 	rrb->cpp = _mesa_get_format_bytes(texImage->TexFormat);
    775 	rrb->pitch = texImage->Width * rrb->cpp;
    776 	rb->Format = texImage->TexFormat;
    777 	rb->InternalFormat = texImage->InternalFormat;
    778 	rb->_BaseFormat = _mesa_base_fbo_format(ctx, rb->InternalFormat);
    779 	rb->Width = texImage->Width;
    780 	rb->Height = texImage->Height;
    781 	rb->Delete = radeon_delete_renderbuffer;
    782 	rb->AllocStorage = radeon_nop_alloc_storage;
    783 
    784 	return GL_TRUE;
    785 }
    786 
    787 
    788 static struct radeon_renderbuffer *
    789 radeon_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage)
    790 {
    791   const GLuint name = ~0;   /* not significant, but distinct for debugging */
    792   struct radeon_renderbuffer *rrb;
    793 
    794    /* make an radeon_renderbuffer to wrap the texture image */
    795    rrb = CALLOC_STRUCT(radeon_renderbuffer);
    796 
    797    radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    798 		"%s(%p, rrb %p, texImage %p) \n",
    799 		__func__, ctx, rrb, texImage);
    800 
    801    if (!rrb) {
    802       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
    803       return NULL;
    804    }
    805 
    806    _mesa_init_renderbuffer(&rrb->base.Base, name);
    807    rrb->base.Base.ClassID = RADEON_RB_CLASS;
    808 
    809    if (!radeon_update_wrapper(ctx, rrb, texImage)) {
    810       free(rrb);
    811       return NULL;
    812    }
    813 
    814    return rrb;
    815 
    816 }
    817 static void
    818 radeon_render_texture(struct gl_context * ctx,
    819                      struct gl_framebuffer *fb,
    820                      struct gl_renderbuffer_attachment *att)
    821 {
    822    struct gl_texture_image *newImage
    823       = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
    824    struct radeon_renderbuffer *rrb = radeon_renderbuffer(att->Renderbuffer);
    825    radeon_texture_image *radeon_image;
    826    GLuint imageOffset;
    827 
    828   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    829 		"%s(%p, fb %p, rrb %p, att %p)\n",
    830 		__func__, ctx, fb, rrb, att);
    831 
    832    (void) fb;
    833 
    834    ASSERT(newImage);
    835 
    836    radeon_image = (radeon_texture_image *)newImage;
    837 
    838    if (!radeon_image->mt) {
    839       /* Fallback on drawing to a texture without a miptree.
    840        */
    841       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
    842       _swrast_render_texture(ctx, fb, att);
    843       return;
    844    }
    845    else if (!rrb) {
    846       rrb = radeon_wrap_texture(ctx, newImage);
    847       if (rrb) {
    848          /* bind the wrapper to the attachment point */
    849          _mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base.Base);
    850       }
    851       else {
    852          /* fallback to software rendering */
    853          _swrast_render_texture(ctx, fb, att);
    854          return;
    855       }
    856    }
    857 
    858    if (!radeon_update_wrapper(ctx, rrb, newImage)) {
    859        _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
    860        _swrast_render_texture(ctx, fb, att);
    861        return;
    862    }
    863 
    864    DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
    865        _glthread_GetID(),
    866        att->Texture->Name, newImage->Width, newImage->Height,
    867        rrb->base.Base.RefCount);
    868 
    869    /* point the renderbufer's region to the texture image region */
    870    if (rrb->bo != radeon_image->mt->bo) {
    871       if (rrb->bo)
    872   	radeon_bo_unref(rrb->bo);
    873       rrb->bo = radeon_image->mt->bo;
    874       radeon_bo_ref(rrb->bo);
    875    }
    876 
    877    /* compute offset of the particular 2D image within the texture region */
    878    imageOffset = radeon_miptree_image_offset(radeon_image->mt,
    879                                             att->CubeMapFace,
    880                                             att->TextureLevel);
    881 
    882    if (att->Texture->Target == GL_TEXTURE_3D) {
    883       imageOffset += radeon_image->mt->levels[att->TextureLevel].rowstride *
    884                      radeon_image->mt->levels[att->TextureLevel].height *
    885                      att->Zoffset;
    886    }
    887 
    888    /* store that offset in the region, along with the correct pitch for
    889     * the image we are rendering to */
    890    rrb->draw_offset = imageOffset;
    891    rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride;
    892    radeon_image->used_as_render_target = GL_TRUE;
    893 
    894    /* update drawing region, etc */
    895    radeon_draw_buffer(ctx, fb);
    896 }
    897 
    898 static void
    899 radeon_finish_render_texture(struct gl_context * ctx,
    900                             struct gl_renderbuffer_attachment *att)
    901 {
    902     struct gl_texture_object *tex_obj = att->Texture;
    903     struct gl_texture_image *image =
    904 	tex_obj->Image[att->CubeMapFace][att->TextureLevel];
    905     radeon_texture_image *radeon_image = (radeon_texture_image *)image;
    906 
    907     if (radeon_image)
    908 	radeon_image->used_as_render_target = GL_FALSE;
    909 
    910     if (ctx->Driver.Flush)
    911         ctx->Driver.Flush(ctx); /* +r6/r7 */
    912 }
    913 static void
    914 radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
    915 {
    916 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
    917 	gl_format mesa_format;
    918 	int i;
    919 
    920 	for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
    921 		struct gl_renderbuffer_attachment *att;
    922 		if (i == -2) {
    923 			att = &fb->Attachment[BUFFER_DEPTH];
    924 		} else if (i == -1) {
    925 			att = &fb->Attachment[BUFFER_STENCIL];
    926 		} else {
    927 			att = &fb->Attachment[BUFFER_COLOR0 + i];
    928 		}
    929 
    930 		if (att->Type == GL_TEXTURE) {
    931 			mesa_format = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->TexFormat;
    932 		} else {
    933 			/* All renderbuffer formats are renderable, but not sampable */
    934 			continue;
    935 		}
    936 
    937 		if (!radeon->vtbl.is_format_renderable(mesa_format)){
    938 			fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
    939 			radeon_print(RADEON_TEXTURE, RADEON_TRACE,
    940 						"%s: HW doesn't support format %s as output format of attachment %d\n",
    941 						__FUNCTION__, _mesa_get_format_name(mesa_format), i);
    942 			return;
    943 		}
    944 	}
    945 }
    946 
    947 void radeon_fbo_init(struct radeon_context *radeon)
    948 {
    949 #if FEATURE_EXT_framebuffer_object
    950   radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer;
    951   radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer;
    952   radeon->glCtx->Driver.MapRenderbuffer = radeon_map_renderbuffer;
    953   radeon->glCtx->Driver.UnmapRenderbuffer = radeon_unmap_renderbuffer;
    954   radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer;
    955   radeon->glCtx->Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer;
    956   radeon->glCtx->Driver.RenderTexture = radeon_render_texture;
    957   radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture;
    958   radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers;
    959   radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer;
    960 #endif
    961 #if FEATURE_EXT_framebuffer_blit
    962   radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
    963 #endif
    964 #if FEATURE_OES_EGL_image
    965   radeon->glCtx->Driver.EGLImageTargetRenderbufferStorage =
    966 	  radeon_image_target_renderbuffer_storage;
    967 #endif
    968 }
    969 
    970 
    971 void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
    972 				struct radeon_bo *bo)
    973 {
    974   struct radeon_bo *old;
    975   old = rb->bo;
    976   rb->bo = bo;
    977   radeon_bo_ref(bo);
    978   if (old)
    979     radeon_bo_unref(old);
    980 }
    981