Merge commit 'origin/master' into gallium-sw-api-2
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_fbo.c
index e780b9eef1b4fee917312c85d6e0c71e11b61cf9..63986058356a79d8efd03ddd0f1e1c9620e11915 100644 (file)
@@ -29,6 +29,7 @@
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/mtypes.h"
+#include "main/enums.h"
 #include "main/fbobject.h"
 #include "main/framebuffer.h"
 #include "main/renderbuffer.h"
@@ -42,7 +43,7 @@
 #define FILE_DEBUG_FLAG RADEON_TEXTURE
 #define DBG(...) do {                                           \
         if (RADEON_DEBUG & FILE_DEBUG_FLAG)                      \
-                _mesa_printf(__VA_ARGS__);                      \
+                printf(__VA_ARGS__);                      \
 } while(0)
 
 static struct gl_framebuffer *
@@ -56,18 +57,26 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
 {
   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
 
+  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+               "%s(rb %p, rrb %p) \n",
+               __func__, rb, rrb);
+
   ASSERT(rrb);
 
   if (rrb && rrb->bo) {
     radeon_bo_unref(rrb->bo);
   }
-  _mesa_free(rrb);
+  free(rrb);
 }
 
 static void *
 radeon_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb,
                   GLint x, GLint y)
 {
+  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+               "%s(%p, rb %p) \n",
+               __func__, ctx, rb);
+
   return NULL;
 }
 
@@ -85,6 +94,10 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
   GLboolean software_buffer = GL_FALSE;
   int cpp;
 
+  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+               "%s(%p, rb %p) \n",
+               __func__, ctx, rb);
+
    ASSERT(rb->Name != 0);
   switch (internalFormat) {
    case GL_R3_G3_B2:
@@ -200,6 +213,10 @@ radeon_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
    rb->Width = width;
    rb->Height = height;
    rb->InternalFormat = internalFormat;
+  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+               "%s(%p, rb %p) \n",
+               __func__, ctx, rb);
+
 
    return GL_TRUE;
 }
@@ -212,6 +229,10 @@ radeon_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb,
      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 */
@@ -252,6 +273,11 @@ radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv)
     struct radeon_renderbuffer *rrb;
 
     rrb = CALLOC_STRUCT(radeon_renderbuffer);
+
+    radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+               "%s( rrb %p ) \n",
+               __func__, rrb);
+
     if (!rrb)
        return NULL;
 
@@ -331,6 +357,11 @@ radeon_new_renderbuffer(GLcontext * ctx, GLuint name)
   struct radeon_renderbuffer *rrb;
 
   rrb = CALLOC_STRUCT(radeon_renderbuffer);
+
+  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+               "%s(%p, rrb %p) \n",
+               __func__, ctx, rrb);
+
   if (!rrb)
     return NULL;
 
@@ -348,6 +379,11 @@ static void
 radeon_bind_framebuffer(GLcontext * 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));
+
    if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
       radeon_draw_buffer(ctx, fb);
    }
@@ -365,82 +401,59 @@ radeon_framebuffer_renderbuffer(GLcontext * ctx,
        if (ctx->Driver.Flush)
                ctx->Driver.Flush(ctx); /* +r6/r7 */
 
+       radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+               "%s(%p, fb %p, rb %p) \n",
+               __func__, ctx, fb, rb);
+
    _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
    radeon_draw_buffer(ctx, fb);
 }
 
-
-/* TODO: According to EXT_fbo spec internal format of texture image
- * once set during glTexImage call, should be preserved when
- * attaching image to renderbuffer. When HW doesn't support
- * rendering to format of attached image, set framebuffer
- * completeness accordingly in radeon_validate_framebuffer (issue #79).
- */
 static GLboolean
 radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb, 
                     struct gl_texture_image *texImage)
 {
-       int retry = 0;
-       gl_format texFormat;
-
-restart:
-       if (texImage->TexFormat == _dri_texformat_argb8888) {
-               rrb->base.DataType = GL_UNSIGNED_BYTE;
-               DBG("Render to RGBA8 texture OK\n");
-       }
-       else if (texImage->TexFormat == _dri_texformat_rgb565) {
-               rrb->base.DataType = GL_UNSIGNED_BYTE;
-               DBG("Render to RGB5 texture OK\n");
-       }
-       else if (texImage->TexFormat == _dri_texformat_argb1555) {
-               rrb->base.DataType = GL_UNSIGNED_BYTE;
-               DBG("Render to ARGB1555 texture OK\n");
-       }
-       else if (texImage->TexFormat == _dri_texformat_argb4444) {
-               rrb->base.DataType = GL_UNSIGNED_BYTE;
-               DBG("Render to ARGB4444 texture OK\n");
+       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;
        }
-       else if (texImage->TexFormat == MESA_FORMAT_Z16) {
-               rrb->base.DataType = GL_UNSIGNED_SHORT;
-               DBG("Render to DEPTH16 texture OK\n");
-       }
-       else if (texImage->TexFormat == MESA_FORMAT_S8_Z24) {
-               rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
-               DBG("Render to DEPTH_STENCIL texture OK\n");
-       }
-       else {
-               /* try redoing the FBO */
-               if (retry == 1) {
-                       DBG("Render to texture BAD FORMAT %d\n",
-                           texImage->TexFormat);
-                       return GL_FALSE;
-               }
-                /* XXX why is the tex format being set here?
-                 * I think this can be removed.
-                 */
-               texImage->TexFormat = radeonChooseTextureFormat(ctx, texImage->InternalFormat, 0,
-                                                               _mesa_get_format_datatype(texImage->TexFormat),
-                                                               1);
-
-               retry++;
-               goto restart;
-       }
-       
-       texFormat = texImage->TexFormat;
-
-       rrb->base.Format = texFormat;
-
-        rrb->cpp = _mesa_get_format_bytes(texFormat);
+               
+       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._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;
-       
+
        return GL_TRUE;
 }
 
@@ -453,6 +466,11 @@ radeon_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage)
 
    /* 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;
@@ -462,7 +480,7 @@ radeon_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage)
    rrb->base.ClassID = RADEON_RB_CLASS;
 
    if (!radeon_update_wrapper(ctx, rrb, texImage)) {
-      _mesa_free(rrb);
+      free(rrb);
       return NULL;
    }
 
@@ -480,6 +498,10 @@ radeon_render_texture(GLcontext * ctx,
    radeon_texture_image *radeon_image;
    GLuint imageOffset;
 
+  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+               "%s(%p, fb %p, rrb %p, att %p)\n",
+               __func__, ctx, fb, rrb, att);
+
    (void) fb;
 
    ASSERT(newImage);
@@ -511,7 +533,7 @@ radeon_render_texture(GLcontext * ctx,
        return;
    }
 
-   DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n",
+   DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
        _glthread_GetID(),
        att->Texture->Name, newImage->Width, newImage->Height,
        rrb->base.RefCount);
@@ -554,6 +576,35 @@ radeon_finish_render_texture(GLcontext * ctx,
 static void
 radeon_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
 {
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       gl_format mesa_format;
+       int i;
+
+       for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
+               struct gl_renderbuffer_attachment *att;
+               if (i == -2) {
+                       att = &fb->Attachment[BUFFER_DEPTH];
+               } else if (i == -1) {
+                       att = &fb->Attachment[BUFFER_STENCIL];
+               } else {
+                       att = &fb->Attachment[BUFFER_COLOR0 + i];
+               }
+
+               if (att->Type == GL_TEXTURE) {
+                       mesa_format = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->TexFormat;
+               } else {
+                       /* All renderbuffer formats are renderable, but not sampable */
+                       continue;
+               }
+
+               if (!radeon->vtbl.is_format_renderable(mesa_format)){
+                       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);
+                       return;
+               }
+       }
 }
 
 void radeon_fbo_init(struct radeon_context *radeon)