gallium: free bitmap fragment shaders, misc clean-up
[mesa.git] / src / mesa / state_tracker / st_cb_fbo.c
index 0d23f7eec40bc28813f3b66a2d10c0157deef716..5384252a8e511dcf57fcbec24649754741ed747a 100644 (file)
 #include "st_cb_texture.h"
 #include "st_format.h"
 #include "st_public.h"
+#include "st_texture.h"
 
 
 
 /**
- * gl_renderbuffer::AllocStorage()
+ * Compute the renderbuffer's Red/Green/EtcBit fields from the pipe format.
  */
-static GLboolean
-st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
-                              GLenum internalFormat,
-                              GLuint width, GLuint height)
+static int
+init_renderbuffer_bits(struct st_renderbuffer *strb,
+                       enum pipe_format pipeFormat)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
-   struct st_renderbuffer *strb = st_renderbuffer(rb);
-   const uint pipeFormat
-      = st_choose_pipe_format(pipe, internalFormat, GL_NONE, GL_NONE);
    struct pipe_format_info info;
-   GLuint cpp;
-   GLbitfield flags = PIPE_SURFACE_FLAG_RENDER; /* want to render to surface */
 
    if (!st_get_format_info( pipeFormat, &info )) {
       assert( 0 );
-      return GL_FALSE;
    }
 
    strb->Base._ActualFormat = info.base_format;
@@ -81,42 +74,66 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
    strb->Base.StencilBits = info.stencil_bits;
    strb->Base.DataType = st_format_datatype(pipeFormat);
 
-   assert(strb->Base.DataType);
+   return info.size;
+}
 
-   cpp = info.size;
 
-   if (strb->surface && strb->surface->format != pipeFormat) {
-      /* need to change surface types, free this surface */
-      pipe_surface_reference(&strb->surface, NULL);
-      assert(strb->surface == NULL);
-   }
+/**
+ * gl_renderbuffer::AllocStorage()
+ */
+static GLboolean
+st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
+                              GLenum internalFormat,
+                              GLuint width, GLuint height)
+{
+   struct pipe_context *pipe = ctx->st->pipe;
+   struct st_renderbuffer *strb = st_renderbuffer(rb);
+   enum pipe_format pipeFormat;
+   GLbitfield flags = 0x0; /* XXX needed? */
 
    if (!strb->surface) {
-      strb->surface = pipe->winsys->surface_alloc(pipe->winsys, pipeFormat);
+      strb->surface = pipe->winsys->surface_alloc(pipe->winsys);
       assert(strb->surface);
+      assert(strb->surface->refcount);
+      assert(strb->surface->winsys);
       if (!strb->surface)
          return GL_FALSE;
    }
 
-   /* free old region */
-   if (strb->surface->region) {
-      /* loop here since mapping is refcounted */
-      struct pipe_region *r = strb->surface->region;
-      while (r->map)
-         pipe->region_unmap(pipe, r);
-      pipe->winsys->region_release(pipe->winsys, &strb->surface->region);
+   if (strb->surface->buffer)
+      pipe_buffer_reference(pipe->winsys, &strb->surface->buffer,
+                           NULL);
+
+   /* Determine surface format here */
+   if (strb->format != PIPE_FORMAT_NONE) {
+      assert(strb->format != 0);
+      /* we'll hit this for front/back color bufs */
+      pipeFormat = strb->format;
+   }
+   else {
+      pipeFormat = st_choose_renderbuffer_format(pipe, internalFormat);
    }
 
-   strb->surface->region = pipe->winsys->region_alloc(pipe->winsys, cpp,
-                                                      width, height, flags);
-   if (!strb->surface->region)
+   init_renderbuffer_bits(strb, pipeFormat);
+
+   pipe->winsys->surface_alloc_storage(pipe->winsys,
+                                       strb->surface,
+                                       width,
+                                       height,
+                                       pipeFormat,
+                                       flags);
+   if (!strb->surface->buffer)
       return GL_FALSE; /* out of memory, try s/w buffer? */
 
-   ASSERT(strb->surface->region->buffer);
+   ASSERT(strb->surface->buffer);
    ASSERT(strb->surface->format);
+   ASSERT(strb->surface->cpp);
+   ASSERT(strb->surface->width == width);
+   ASSERT(strb->surface->height == height);
+   ASSERT(strb->surface->pitch);
 
-   strb->Base.Width  = strb->surface->width  = width;
-   strb->Base.Height = strb->surface->height = height;
+   strb->Base.Width  = width;
+   strb->Base.Height = height;
 
    return GL_TRUE;
 }
@@ -178,6 +195,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name)
       strb->Base.Delete = st_renderbuffer_delete;
       strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
       strb->Base.GetPointer = null_get_pointer;
+      strb->format = PIPE_FORMAT_NONE;
       return &strb->Base;
    }
    return NULL;
@@ -186,10 +204,10 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name)
 
 /**
  * Allocate a renderbuffer for a an on-screen window (not a user-created
- * renderbuffer).  The window system code determines the internal format.
+ * renderbuffer).  The window system code determines the format.
  */
 struct gl_renderbuffer *
-st_new_renderbuffer_fb(GLenum intFormat)
+st_new_renderbuffer_fb(enum pipe_format format)
 {
    struct st_renderbuffer *strb;
 
@@ -201,27 +219,41 @@ st_new_renderbuffer_fb(GLenum intFormat)
 
    _mesa_init_renderbuffer(&strb->Base, 0);
    strb->Base.ClassID = 0x4242; /* just a unique value */
-   strb->Base.InternalFormat = intFormat;
-
-   switch (intFormat) {
-   case GL_RGB5:
-   case GL_RGBA8:
-   case GL_RGBA16:
+   strb->format = format;
+
+   switch (format) {
+   case PIPE_FORMAT_A8R8G8B8_UNORM:
+   case PIPE_FORMAT_B8G8R8A8_UNORM:
+   case PIPE_FORMAT_A1R5G5B5_UNORM:
+   case PIPE_FORMAT_A4R4G4B4_UNORM:
+   case PIPE_FORMAT_R5G6B5_UNORM:
+      strb->Base.InternalFormat = GL_RGBA;
       strb->Base._BaseFormat = GL_RGBA;
       break;
-   case GL_DEPTH_COMPONENT16:
-   case GL_DEPTH_COMPONENT32:
+   case PIPE_FORMAT_Z16_UNORM:
+      strb->Base.InternalFormat = GL_DEPTH_COMPONENT16;
+      strb->Base._BaseFormat = GL_DEPTH_COMPONENT;
+      break;
+   case PIPE_FORMAT_Z32_UNORM:
+      strb->Base.InternalFormat = GL_DEPTH_COMPONENT32;
       strb->Base._BaseFormat = GL_DEPTH_COMPONENT;
       break;
-   case GL_DEPTH24_STENCIL8_EXT:
+   case PIPE_FORMAT_S8Z24_UNORM:
+   case PIPE_FORMAT_Z24S8_UNORM:
+      strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT;
       strb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT;
       break;
-   case GL_STENCIL_INDEX8_EXT:
+   case PIPE_FORMAT_S8_UNORM:
+      strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
       strb->Base._BaseFormat = GL_STENCIL_INDEX;
       break;
+   case PIPE_FORMAT_R16G16B16A16_SNORM:
+      strb->Base.InternalFormat = GL_RGBA16;
+      strb->Base._BaseFormat = GL_RGBA;
+      break;
    default:
       _mesa_problem(NULL,
-                   "Unexpected intFormat in st_new_renderbuffer");
+                   "Unexpected format in st_new_renderbuffer_fb");
       return NULL;
    }
 
@@ -238,6 +270,7 @@ st_new_renderbuffer_fb(GLenum intFormat)
 
 
 
+
 /**
  * Called via ctx->Driver.BindFramebufferEXT().
  */
@@ -274,7 +307,8 @@ st_render_texture(GLcontext *ctx,
    struct st_renderbuffer *strb;
    struct gl_renderbuffer *rb;
    struct pipe_context *pipe = st->pipe;
-   struct pipe_mipmap_tree *mt;
+   struct pipe_screen *screen = pipe->screen;
+   struct pipe_texture *pt;
 
    assert(!att->Renderbuffer);
 
@@ -290,24 +324,26 @@ st_render_texture(GLcontext *ctx,
    rb->AllocStorage = NULL; /* should not get called */
    strb = st_renderbuffer(rb);
 
-   /* get the mipmap tree for the texture */
-   mt = st_get_texobj_mipmap_tree(att->Texture);
-   assert(mt);
-   assert(mt->level[att->TextureLevel].width);
+   /* get the texture for the texture object */
+   pt = st_get_texobj_texture(att->Texture);
+   assert(pt);
+   assert(pt->width[att->TextureLevel]);
 
-   rb->Width = mt->level[att->TextureLevel].width;
-   rb->Height = mt->level[att->TextureLevel].height;
+   rb->Width = pt->width[att->TextureLevel];
+   rb->Height = pt->height[att->TextureLevel];
 
-   /* the renderbuffer's surface is inside the mipmap_tree: */
-   strb->surface = pipe->get_tex_surface(pipe, mt,
-                                         att->CubeMapFace,
-                                         att->TextureLevel,
-                                         att->Zoffset);
+   /* the renderbuffer's surface is inside the texture */
+   strb->surface = screen->get_tex_surface(screen, pt,
+                                           att->CubeMapFace,
+                                           att->TextureLevel,
+                                           att->Zoffset);
    assert(strb->surface);
 
+   init_renderbuffer_bits(strb, pt->format);
+
    /*
-   printf("RENDER TO TEXTURE obj=%p mt=%p surf=%p  %d x %d\n",
-          att->Texture, mt, strb->surface, rb->Width, rb->Height);
+   printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p  %d x %d\n",
+          att->Texture, pt, strb->surface, rb->Width, rb->Height);
    */
 
    /* Invalidate buffer state so that the pipe's framebuffer state
@@ -330,7 +366,7 @@ st_finish_render_texture(GLcontext *ctx,
 
    assert(strb);
 
-   ctx->st->pipe->flush(ctx->st->pipe, 0x0);
+   ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE);
 
    /*
    printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface);