mesa: handle some cases of 0x0 render targets
[mesa.git] / src / mesa / state_tracker / st_cb_fbo.c
index 2368c31f4b46060580b1ccd2cfd12555a549d50c..45a05421f8ecd56437458364db221a3de80eefac 100644 (file)
@@ -77,12 +77,6 @@ init_renderbuffer_bits(struct st_renderbuffer *strb,
    return info.size;
 }
 
-static INLINE GLboolean pf_is_depth_stencil( enum pipe_format format )
-{
-   return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) +
-           pf_get_component_bits( format, PIPE_FORMAT_COMP_S )) != 0;
-}
-
 /**
  * gl_renderbuffer::AllocStorage()
  * This is called to allocate the original drawing surface, and
@@ -98,10 +92,11 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
    struct pipe_texture template;
    unsigned surface_usage;
 
-   /* Free the old surface (and texture if we hold the last
-    * reference):
+   /* Free the old surface and texture
     */
    pipe_surface_reference( &strb->surface, NULL );
+   pipe_texture_reference( &strb->texture, NULL );
+
 
    memset(&template, 0, sizeof(template));
 
@@ -118,11 +113,12 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
 
    template.target = PIPE_TEXTURE_2D;
    template.compressed = 0;
-   template.cpp = pf_get_size(template.format);
+   pf_get_block(template.format, &template.block);
    template.width[0] = width;
    template.height[0] = height;
    template.depth[0] = 1;
    template.last_level = 0;
+   template.nr_samples = rb->Samples;
 
    if (pf_is_depth_stencil(template.format)) {
       template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
@@ -174,12 +170,15 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
                                                   0, 0, 0,
                                                   surface_usage );
 
+   assert(strb->surface->texture);
    assert(strb->surface->buffer);
    assert(strb->surface->format);
-   assert(strb->surface->cpp);
+   assert(strb->surface->block.size);
+   assert(strb->surface->block.width);
+   assert(strb->surface->block.height);
    assert(strb->surface->width == width);
    assert(strb->surface->height == height);
-   assert(strb->surface->pitch);
+   assert(strb->surface->stride);
 
 
    return strb->surface != NULL;
@@ -252,7 +251,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name)
  * renderbuffer).  The window system code determines the format.
  */
 struct gl_renderbuffer *
-st_new_renderbuffer_fb(enum pipe_format format)
+st_new_renderbuffer_fb(enum pipe_format format, int samples)
 {
    struct st_renderbuffer *strb;
 
@@ -264,6 +263,7 @@ st_new_renderbuffer_fb(enum pipe_format format)
 
    _mesa_init_renderbuffer(&strb->Base, 0);
    strb->Base.ClassID = 0x4242; /* just a unique value */
+   strb->Base.Samples = samples;
    strb->format = format;
 
    switch (format) {
@@ -352,11 +352,8 @@ st_render_texture(GLcontext *ctx,
                   struct gl_framebuffer *fb,
                   struct gl_renderbuffer_attachment *att)
 {
-   struct st_context *st = ctx->st;
    struct st_renderbuffer *strb;
    struct gl_renderbuffer *rb;
-   struct pipe_context *pipe = st->pipe;
-   struct pipe_screen *screen = pipe->screen;
    struct pipe_texture *pt;
    struct st_texture_object *stObj;
    const struct gl_texture_image *texImage =
@@ -391,29 +388,17 @@ st_render_texture(GLcontext *ctx,
    /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/
 
    pt = st_get_texobj_texture(att->Texture);
-   assert(pt);
-   /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/
 
    pipe_texture_reference( &strb->texture, pt );
 
    pipe_surface_reference(&strb->surface, NULL);
 
-#if 0
-   /* the renderbuffer's surface is inside the texture */
-   strb->surface = screen->get_tex_surface(screen, pt,
-                                           att->CubeMapFace,
-                                           att->TextureLevel /*- att->Texture->BaseLevel*/,
-                                           att->Zoffset,
-                                           PIPE_BUFFER_USAGE_GPU_READ |
-                                           PIPE_BUFFER_USAGE_GPU_WRITE);
-   printf("***** surface size: %d x %d\n", strb->surface->width, strb->surface->height);
-
-   assert(strb->surface);
-   assert(screen->is_format_supported(screen, strb->surface->format, PIPE_TEXTURE));
-   assert(screen->is_format_supported(screen, strb->surface->format, PIPE_SURFACE));
-
-   init_renderbuffer_bits(strb, pt->format);
-#endif
+   /* the new surface will be created during framebuffer validation */
+
+   if (pt) {
+      /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/
+      init_renderbuffer_bits(strb, pt->format);
+   }
 
    /*
    printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p  %d x %d\n",
@@ -439,9 +424,10 @@ st_finish_render_texture(GLcontext *ctx,
    struct pipe_screen *screen = ctx->st->pipe->screen;
    struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer);
 
-   assert(strb);
+   if (!strb)
+      return;
 
-   ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+   st_flush( ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL );
 
    if (strb->surface)
       screen->tex_surface_release( screen, &strb->surface );