radeon: some more fbo work
authorDave Airlie <airlied@linux.ie>
Fri, 20 Mar 2009 12:07:05 +0000 (22:07 +1000)
committerDave Airlie <airlied@linux.ie>
Fri, 20 Mar 2009 12:07:05 +0000 (22:07 +1000)
src/mesa/drivers/dri/radeon/radeon_common.h
src/mesa/drivers/dri/radeon/radeon_fbo.c
src/mesa/drivers/dri/radeon/radeon_screen.c

index d3eee7d88858acf100d59c025d742b2aa2fd1af5..a3fea28a2991b0f54ef82824c763fcf46d901891 100644 (file)
@@ -31,7 +31,8 @@ void radeonReadBuffer( GLcontext *ctx, GLenum mode );
 void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height);
 
 void radeon_fbo_init(struct radeon_context *radeon);
-
+struct gl_renderbuffer *
+radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv);
 static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb)
 {
        struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb;
index 56e5cbcbc81735cdc7c3956ea05936c5ca0f4aff..649f88a061cfe733a3f6a6ec3565cad692812a31 100644 (file)
 
 #include "radeon_common.h"
 
+#define FILE_DEBUG_FLAG DEBUG_TEXTURE
+#define DBG(...) do {                                           \
+        if (RADEON_DEBUG & FILE_DEBUG_FLAG)                      \
+                _mesa_printf(__VA_ARGS__);                      \
+} while(0)
+
 static struct gl_framebuffer *
 radeon_new_framebuffer(GLcontext *ctx, GLuint name)
 {
@@ -60,13 +66,6 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
   _mesa_free(rrb);
 }
 
-static void
-radeon_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb,
-                    GLuint width, GLuint height)
-{
-
-}
-
 static void *
 radeon_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb,
                   GLint x, GLint y)
@@ -89,18 +88,236 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
   int cpp;
 
    ASSERT(rb->Name != 0);
+  switch (internalFormat) {
+   case GL_R3_G3_B2:
+   case GL_RGB4:
+   case GL_RGB5:
+      rb->_ActualFormat = GL_RGB5;
+      rb->DataType = GL_UNSIGNED_BYTE;
+      rb->RedBits = 5;
+      rb->GreenBits = 6;
+      rb->BlueBits = 5;
+      cpp = 2;
+      break;
+   case GL_RGB:
+   case GL_RGB8:
+   case GL_RGB10:
+   case GL_RGB12:
+   case GL_RGB16:
+      rb->_ActualFormat = GL_RGB8;
+      rb->DataType = GL_UNSIGNED_BYTE;
+      rb->RedBits = 8;
+      rb->GreenBits = 8;
+      rb->BlueBits = 8;
+      rb->AlphaBits = 0;
+      cpp = 4;
+      break;
+   case GL_RGBA:
+   case GL_RGBA2:
+   case GL_RGBA4:
+   case GL_RGB5_A1:
+   case GL_RGBA8:
+   case GL_RGB10_A2:
+   case GL_RGBA12:
+   case GL_RGBA16:
+      rb->_ActualFormat = GL_RGBA8;
+      rb->DataType = GL_UNSIGNED_BYTE;
+      rb->RedBits = 8;
+      rb->GreenBits = 8;
+      rb->BlueBits = 8;
+      rb->AlphaBits = 8;
+      cpp = 4;
+      break;
+   case GL_STENCIL_INDEX:
+   case GL_STENCIL_INDEX1_EXT:
+   case GL_STENCIL_INDEX4_EXT:
+   case GL_STENCIL_INDEX8_EXT:
+   case GL_STENCIL_INDEX16_EXT:
+      /* alloc a depth+stencil buffer */
+      rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
+      rb->StencilBits = 8;
+      cpp = 4;
+      break;
+   case GL_DEPTH_COMPONENT16:
+      rb->_ActualFormat = GL_DEPTH_COMPONENT16;
+      rb->DataType = GL_UNSIGNED_SHORT;
+      rb->DepthBits = 16;
+      cpp = 2;
+      break;
+   case GL_DEPTH_COMPONENT:
+   case GL_DEPTH_COMPONENT24:
+   case GL_DEPTH_COMPONENT32:
+      rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
+      rb->DepthBits = 24;
+      cpp = 4;
+      break;
+   case GL_DEPTH_STENCIL_EXT:
+   case GL_DEPTH24_STENCIL8_EXT:
+      rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
+      rb->DepthBits = 24;
+      rb->StencilBits = 8;
+      cpp = 4;
+      break;
+   default:
+      _mesa_problem(ctx,
+                    "Unexpected format in intel_alloc_renderbuffer_storage");
+      return GL_FALSE;
+   }
 
+  radeonFlush(ctx);
+
+  if (rrb->bo)
+    radeon_bo_unref(rrb->bo);
+  
+    
    if (software_buffer) {
       return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat,
                                              width, height);
    }
    else {
      /* TODO Alloc a BO */
+
+     //     rrb->bo = radeon_bo_open();
+     rb->Width = width;
+     rb->Height = height;
        return GL_TRUE;
    }    
    
 }
 
+
+/**
+ * Called for each hardware renderbuffer when a _window_ is resized.
+ * Just update fields.
+ * Not used for user-created renderbuffers!
+ */
+static GLboolean
+radeon_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
+                           GLenum internalFormat, GLuint width, GLuint height)
+{
+   ASSERT(rb->Name == 0);
+   rb->Width = width;
+   rb->Height = height;
+   rb->_ActualFormat = internalFormat;
+
+   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;
+
+   _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)
+{
+   _mesa_problem(ctx, "radeon_op_alloc_storage should never be called.");
+   return GL_FALSE;
+}
+
+struct gl_renderbuffer *
+radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
+{
+    struct radeon_renderbuffer *rrb;
+
+    rrb = CALLOC_STRUCT(radeon_renderbuffer);
+    if (!rrb)
+       return NULL;
+
+    _mesa_init_renderbuffer(&rrb->base, 0);
+    rrb->base.ClassID = RADEON_RB_CLASS;
+
+    /* XXX format junk */
+    switch (format) {
+       case GL_RGB5:
+           rrb->base._ActualFormat = GL_RGB5;
+           rrb->base._BaseFormat = GL_RGBA;
+           rrb->base.RedBits = 5;
+           rrb->base.GreenBits = 6;
+           rrb->base.BlueBits = 5;
+           rrb->base.DataType = GL_UNSIGNED_BYTE;
+           break;
+       case GL_RGBA8:
+           rrb->base._ActualFormat = GL_RGBA8;
+           rrb->base._BaseFormat = GL_RGBA;
+           rrb->base.RedBits = 8;
+           rrb->base.GreenBits = 8;
+           rrb->base.BlueBits = 8;
+           rrb->base.AlphaBits = 8;
+           rrb->base.DataType = GL_UNSIGNED_BYTE;
+           break;
+       case GL_STENCIL_INDEX8_EXT:
+           rrb->base._ActualFormat = GL_STENCIL_INDEX8_EXT;
+           rrb->base._BaseFormat = GL_STENCIL_INDEX;
+           rrb->base.StencilBits = 8;
+           rrb->base.DataType = GL_UNSIGNED_BYTE;
+           break;
+       case GL_DEPTH_COMPONENT16:
+           rrb->base._ActualFormat = GL_DEPTH_COMPONENT16;
+           rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
+           rrb->base.DepthBits = 16;
+           rrb->base.DataType = GL_UNSIGNED_SHORT;
+           break;
+       case GL_DEPTH_COMPONENT24:
+           rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+           rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
+           rrb->base.DepthBits = 24;
+           rrb->base.DataType = GL_UNSIGNED_INT;
+           break;
+       case GL_DEPTH24_STENCIL8_EXT:
+           rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+           rrb->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
+           rrb->base.DepthBits = 24;
+           rrb->base.StencilBits = 8;
+           rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
+           break;
+       default:
+           fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format);
+           _mesa_delete_renderbuffer(&rrb->base);
+           return NULL;
+    }
+
+    rrb->dPriv = driDrawPriv;
+    rrb->base.InternalFormat = format;
+
+    rrb->base.Delete = radeon_delete_renderbuffer;
+    rrb->base.AllocStorage = radeon_alloc_window_storage;
+    rrb->base.GetPointer = radeon_get_pointer;
+
+    radeonSetSpanFunctions(rrb);
+
+    rrb->bo = NULL;
+    return &rrb->base;
+}
+
 static struct gl_renderbuffer *
 radeon_new_renderbuffer(GLcontext * ctx, GLuint name)
 {
@@ -120,6 +337,7 @@ radeon_new_renderbuffer(GLcontext * ctx, GLuint name)
   return &rrb->base;
 }
 
+
 static void
 radeon_bind_framebuffer(GLcontext * ctx, GLenum target,
                        struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
@@ -144,10 +362,80 @@ radeon_framebuffer_renderbuffer(GLcontext * ctx,
    radeon_draw_buffer(ctx, fb);
 }
 
+
+static GLboolean
+radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb, 
+                    struct gl_texture_image *texImage)
+{
+   if (texImage->TexFormat == &_mesa_texformat_argb8888) {
+      rrb->base._ActualFormat = GL_RGBA8;
+      rrb->base._BaseFormat = GL_RGBA;
+      rrb->base.DataType = GL_UNSIGNED_BYTE;
+      DBG("Render to RGBA8 texture OK\n");
+   }
+   else if (texImage->TexFormat == &_mesa_texformat_rgb565) {
+      rrb->base._ActualFormat = GL_RGB5;
+      rrb->base._BaseFormat = GL_RGB;
+      rrb->base.DataType = GL_UNSIGNED_SHORT;
+      DBG("Render to RGB5 texture OK\n");
+   }
+   else if (texImage->TexFormat == &_mesa_texformat_z16) {
+      rrb->base._ActualFormat = GL_DEPTH_COMPONENT16;
+      rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
+      rrb->base.DataType = GL_UNSIGNED_SHORT;
+      DBG("Render to DEPTH16 texture OK\n");
+   }
+   else if (texImage->TexFormat == &_mesa_texformat_s8_z24) {
+      rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+      rrb->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
+      rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
+      DBG("Render to DEPTH_STENCIL texture OK\n");
+   }
+   else {
+      DBG("Render to texture BAD FORMAT %d\n",
+         texImage->TexFormat->MesaFormat);
+      return GL_FALSE;
+   }
+
+   rrb->base.InternalFormat = rrb->base._ActualFormat;
+   rrb->base.Width = texImage->Width;
+   rrb->base.Height = texImage->Height;
+   rrb->base.RedBits = texImage->TexFormat->RedBits;
+   rrb->base.GreenBits = texImage->TexFormat->GreenBits;
+   rrb->base.BlueBits = texImage->TexFormat->BlueBits;
+   rrb->base.AlphaBits = texImage->TexFormat->AlphaBits;
+   rrb->base.DepthBits = texImage->TexFormat->DepthBits;
+
+   rrb->base.Delete = radeon_delete_renderbuffer;
+   rrb->base.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);
+   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)) {
+      _mesa_free(rrb);
+      return NULL;
+   }
+
+   return rrb;
+  
 }
 static void
 radeon_render_texture(GLcontext * ctx,
index 1d4f008cbc7acc63df419836b14ab526f677e3ff..a14a0c3cb286cb5179c315d2987efd765b12d442 100644 (file)
@@ -1175,90 +1175,7 @@ radeonInitDriver( __DRIscreenPrivate *sPriv )
     return GL_TRUE;
 }
 
-static GLboolean
-radeon_alloc_window_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
-                           GLenum intFormat, GLuint w, GLuint h)
-{
-    rb->Width = w;
-    rb->Height = h;
-    rb->_ActualFormat = intFormat;
-
-    return GL_TRUE;
-}
-
-
-static struct radeon_renderbuffer *
-radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
-{
-    struct radeon_renderbuffer *ret;
 
-    ret = CALLOC_STRUCT(radeon_renderbuffer);
-    if (!ret)
-       return NULL;
-
-    _mesa_init_renderbuffer(&ret->base, 0);
-    ret->base.ClassID = RADEON_RB_CLASS;
-
-    /* XXX format junk */
-    switch (format) {
-       case GL_RGB5:
-           ret->base._ActualFormat = GL_RGB5;
-           ret->base._BaseFormat = GL_RGBA;
-           ret->base.RedBits = 5;
-           ret->base.GreenBits = 6;
-           ret->base.BlueBits = 5;
-           ret->base.DataType = GL_UNSIGNED_BYTE;
-           break;
-       case GL_RGBA8:
-           ret->base._ActualFormat = GL_RGBA8;
-           ret->base._BaseFormat = GL_RGBA;
-           ret->base.RedBits = 8;
-           ret->base.GreenBits = 8;
-           ret->base.BlueBits = 8;
-           ret->base.AlphaBits = 8;
-           ret->base.DataType = GL_UNSIGNED_BYTE;
-           break;
-       case GL_STENCIL_INDEX8_EXT:
-           ret->base._ActualFormat = GL_STENCIL_INDEX8_EXT;
-           ret->base._BaseFormat = GL_STENCIL_INDEX;
-           ret->base.StencilBits = 8;
-           ret->base.DataType = GL_UNSIGNED_BYTE;
-           break;
-       case GL_DEPTH_COMPONENT16:
-           ret->base._ActualFormat = GL_DEPTH_COMPONENT16;
-           ret->base._BaseFormat = GL_DEPTH_COMPONENT;
-           ret->base.DepthBits = 16;
-           ret->base.DataType = GL_UNSIGNED_SHORT;
-           break;
-       case GL_DEPTH_COMPONENT24:
-           ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
-           ret->base._BaseFormat = GL_DEPTH_COMPONENT;
-           ret->base.DepthBits = 24;
-           ret->base.DataType = GL_UNSIGNED_INT;
-           break;
-       case GL_DEPTH24_STENCIL8_EXT:
-           ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
-           ret->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
-           ret->base.DepthBits = 24;
-           ret->base.StencilBits = 8;
-           ret->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
-           break;
-       default:
-           fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format);
-           _mesa_delete_renderbuffer(&ret->base);
-           return NULL;
-    }
-
-    ret->dPriv = driDrawPriv;
-    ret->base.InternalFormat = format;
-
-    ret->base.AllocStorage = radeon_alloc_window_storage;
-
-    radeonSetSpanFunctions(ret);
-
-    ret->bo = NULL;
-    return ret;
-}
 
 /**
  * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
@@ -1298,29 +1215,29 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
        depthFormat = GL_DEPTH_COMPONENT24;
 
     /* front color renderbuffer */
-    rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
+    rfb->color_rb[0] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv));
     _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
     rfb->color_rb[0]->has_surface = 1;
 
     /* back color renderbuffer */
     if (mesaVis->doubleBufferMode) {
-       rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
+      rfb->color_rb[1] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv));
        _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
        rfb->color_rb[1]->has_surface = 1;
     }
 
     /* depth renderbuffer */
     if (depthFormat != GL_NONE) {
-       struct radeon_renderbuffer *depth =
-           radeon_create_renderbuffer(depthFormat, driDrawPriv);
+      struct radeon_renderbuffer *depth = radeon_renderbuffer(
+                                                             radeon_create_renderbuffer(depthFormat, driDrawPriv));
        _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
        depth->has_surface = screen->depthHasSurface;
     }
 
     /* stencil renderbuffer */
     if (mesaVis->stencilBits > 0 && !swStencil) {
-       struct radeon_renderbuffer *stencil =
-           radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv);
+      struct radeon_renderbuffer *stencil = radeon_renderbuffer(
+                                                               radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv));
        _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &stencil->base);
        stencil->has_surface = screen->depthHasSurface;
     }