st/mesa: handle new GLSL IR enumerants in switch statements
[mesa.git] / src / mesa / state_tracker / st_cb_fbo.c
index 88c6fa2da9616743c444f061e2366d6bfcb53cba..d042ebabfd8a6c0fcdbe0c5758a507167d019ff6 100644 (file)
@@ -113,7 +113,7 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx,
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = st->pipe->screen;
    struct st_renderbuffer *strb = st_renderbuffer(rb);
-   enum pipe_format format;
+   enum pipe_format format = PIPE_FORMAT_NONE;
    struct pipe_surface surf_tmpl;
    struct pipe_resource templ;
 
@@ -133,8 +133,36 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx,
    pipe_surface_reference( &strb->surface, NULL );
    pipe_resource_reference( &strb->texture, NULL );
 
-   format = st_choose_renderbuffer_format(screen, internalFormat,
-                                          rb->NumSamples);
+   /* Handle multisample renderbuffers first.
+    *
+    * From ARB_framebuffer_object:
+    *   If <samples> is zero, then RENDERBUFFER_SAMPLES is set to zero.
+    *   Otherwise <samples> represents a request for a desired minimum
+    *   number of samples. Since different implementations may support
+    *   different sample counts for multisampled rendering, the actual
+    *   number of samples allocated for the renderbuffer image is
+    *   implementation dependent.  However, the resulting value for
+    *   RENDERBUFFER_SAMPLES is guaranteed to be greater than or equal
+    *   to <samples> and no more than the next larger sample count supported
+    *   by the implementation.
+    *
+    * So let's find the supported number of samples closest to NumSamples.
+    * (NumSamples == 1) is treated the same as (NumSamples == 0).
+    */
+   if (rb->NumSamples > 1) {
+      unsigned i;
+
+      for (i = rb->NumSamples; i <= ctx->Const.MaxSamples; i++) {
+         format = st_choose_renderbuffer_format(screen, internalFormat, i);
+
+         if (format != PIPE_FORMAT_NONE) {
+            rb->NumSamples = i;
+            break;
+         }
+      }
+   } else {
+      format = st_choose_renderbuffer_format(screen, internalFormat, 0);
+   }
 
    /* Not setting gl_renderbuffer::Format here will cause
     * FRAMEBUFFER_UNSUPPORTED and ValidateFramebuffer will not be called.
@@ -178,7 +206,7 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx,
    if (!strb->texture)
       return FALSE;
 
-   u_surface_default_template(&surf_tmpl, strb->texture, templ.bind);
+   u_surface_default_template(&surf_tmpl, strb->texture);
    strb->surface = pipe->create_surface(pipe,
                                         strb->texture,
                                         &surf_tmpl);
@@ -197,14 +225,16 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx,
  * gl_renderbuffer::Delete()
  */
 static void
-st_renderbuffer_delete(struct gl_renderbuffer *rb)
+st_renderbuffer_delete(struct gl_context *ctx, struct gl_renderbuffer *rb)
 {
    struct st_renderbuffer *strb = st_renderbuffer(rb);
-   ASSERT(strb);
-   pipe_surface_reference(&strb->surface, NULL);
+   if (ctx) {
+      struct st_context *st = st_context(ctx);
+      pipe_surface_release(st->pipe, &strb->surface);
+   }
    pipe_resource_reference(&strb->texture, NULL);
    free(strb->data);
-   free(strb);
+   _mesa_delete_renderbuffer(ctx, rb);
 }
 
 
@@ -263,13 +293,21 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
    case PIPE_FORMAT_R8G8B8A8_UNORM:
    case PIPE_FORMAT_B8G8R8A8_UNORM:
    case PIPE_FORMAT_A8R8G8B8_UNORM:
+      strb->Base.InternalFormat = GL_RGBA8;
+      break;
    case PIPE_FORMAT_R8G8B8X8_UNORM:
    case PIPE_FORMAT_B8G8R8X8_UNORM:
    case PIPE_FORMAT_X8R8G8B8_UNORM:
+      strb->Base.InternalFormat = GL_RGB8;
+      break;
    case PIPE_FORMAT_B5G5R5A1_UNORM:
+      strb->Base.InternalFormat = GL_RGB5_A1;
+      break;
    case PIPE_FORMAT_B4G4R4A4_UNORM:
+      strb->Base.InternalFormat = GL_RGBA4;
+      break;
    case PIPE_FORMAT_B5G6R5_UNORM:
-      strb->Base.InternalFormat = GL_RGBA;
+      strb->Base.InternalFormat = GL_RGB565;
       break;
    case PIPE_FORMAT_Z16_UNORM:
       strb->Base.InternalFormat = GL_DEPTH_COMPONENT16;
@@ -279,9 +317,11 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
       break;
    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
+      strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT;
+      break;
    case PIPE_FORMAT_Z24X8_UNORM:
    case PIPE_FORMAT_X8Z24_UNORM:
-      strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT;
+      strb->Base.InternalFormat = GL_DEPTH_COMPONENT24;
       break;
    case PIPE_FORMAT_S8_UINT:
       strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
@@ -398,7 +438,7 @@ st_render_texture(struct gl_context *ctx,
 
    pipe_resource_reference( &strb->texture, pt );
 
-   pipe_surface_reference(&strb->surface, NULL);
+   pipe_surface_release(pipe, &strb->surface);
 
    assert(strb->rtt_level <= strb->texture->last_level);
 
@@ -406,7 +446,6 @@ st_render_texture(struct gl_context *ctx,
    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
    surf_tmpl.format = ctx->Color.sRGBEnabled
       ? strb->texture->format : util_format_linear(strb->texture->format);
-   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
    surf_tmpl.u.tex.level = strb->rtt_level;
    surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
    surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
@@ -422,6 +461,12 @@ st_render_texture(struct gl_context *ctx,
     * passed to the pipe as a (color/depth) render target.
     */
    st_invalidate_state(ctx, _NEW_BUFFERS);
+
+
+   /* Need to trigger a call to update_framebuffer() since we just
+    * attached a new renderbuffer.
+    */
+   ctx->NewState |= _NEW_BUFFERS;
 }
 
 
@@ -444,6 +489,16 @@ st_finish_render_texture(struct gl_context *ctx,
 }
 
 
+/** Debug helper */
+static void
+st_fbo_invalid(const char *reason)
+{
+   if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) {
+      _mesa_debug(NULL, "Invalid FBO: %s\n", reason);
+   }
+}
+
+
 /**
  * Validate a renderbuffer attachment for a particular set of bindings.
  */
@@ -456,6 +511,7 @@ st_validate_attachment(struct gl_context *ctx,
    const struct st_texture_object *stObj = st_texture_object(att->Texture);
    enum pipe_format format;
    gl_format texFormat;
+   GLboolean valid;
 
    /* Only validate texture attachments for now, since
     * st_renderbuffer_alloc_storage makes sure that
@@ -479,9 +535,14 @@ st_validate_attachment(struct gl_context *ctx,
       format = st_mesa_format_to_pipe_format(linearFormat);
    }
 
-   return screen->is_format_supported(screen, format,
+   valid = screen->is_format_supported(screen, format,
                                       PIPE_TEXTURE_2D,
                                       stObj->pt->nr_samples, bindings);
+   if (!valid) {
+      st_fbo_invalid("Invalid format");
+   }
+
+   return valid;
 }
 
 
@@ -530,12 +591,14 @@ st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
          screen->get_param(screen, PIPE_CAP_MIXED_COLORBUFFER_FORMATS) != 0;
 
    if (depth->Type && stencil->Type && depth->Type != stencil->Type) {
+      st_fbo_invalid("Different Depth/Stencil buffer formats");
       fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
       return;
    }
    if (depth->Type == GL_RENDERBUFFER_EXT &&
        stencil->Type == GL_RENDERBUFFER_EXT &&
        depth->Renderbuffer != stencil->Renderbuffer) {
+      st_fbo_invalid("Separate Depth/Stencil buffers");
       fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
       return;
    }
@@ -543,6 +606,7 @@ st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
        stencil->Type == GL_TEXTURE &&
        depth->Texture != stencil->Texture) {
       fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+      st_fbo_invalid("Different Depth/Stencil textures");
       return;
    }
 
@@ -585,6 +649,7 @@ st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
             first_format = format;
          } else if (format != first_format) {
             fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+            st_fbo_invalid("Mixed color formats");
             return;
          }
       }
@@ -646,6 +711,7 @@ st_MapRenderbuffer(struct gl_context *ctx,
    const GLboolean invert = rb->Name == 0;
    unsigned usage;
    GLuint y2;
+   GLubyte *map;
 
    if (strb->software) {
       /* software-allocated renderbuffer (probably an accum buffer) */
@@ -680,15 +746,14 @@ st_MapRenderbuffer(struct gl_context *ctx,
    else
       y2 = y;
 
-   strb->transfer = pipe_get_transfer(pipe,
-                                      strb->texture,
-                                      strb->rtt_level,
-                                      strb->rtt_face + strb->rtt_slice,
-                                      usage, x, y2, w, h);
-   if (strb->transfer) {
-      GLubyte *map = pipe_transfer_map(pipe, strb->transfer);
+    map = pipe_transfer_map(pipe,
+                            strb->texture,
+                            strb->rtt_level,
+                            strb->rtt_face + strb->rtt_slice,
+                            usage, x, y2, w, h, &strb->transfer);
+   if (map) {
       if (invert) {
-         *rowStrideOut = -strb->transfer->stride;
+         *rowStrideOut = -(int) strb->transfer->stride;
          map += (h - 1) * strb->transfer->stride;
       }
       else {
@@ -720,7 +785,6 @@ st_UnmapRenderbuffer(struct gl_context *ctx,
    }
 
    pipe_transfer_unmap(pipe, strb->transfer);
-   pipe->transfer_destroy(pipe, strb->transfer);
    strb->transfer = NULL;
 }
 
@@ -728,7 +792,6 @@ st_UnmapRenderbuffer(struct gl_context *ctx,
 
 void st_init_fbo_functions(struct dd_function_table *functions)
 {
-#if FEATURE_EXT_framebuffer_object
    functions->NewFramebuffer = st_new_framebuffer;
    functions->NewRenderbuffer = st_new_renderbuffer;
    functions->BindFramebuffer = st_bind_framebuffer;
@@ -736,7 +799,6 @@ void st_init_fbo_functions(struct dd_function_table *functions)
    functions->RenderTexture = st_render_texture;
    functions->FinishRenderTexture = st_finish_render_texture;
    functions->ValidateFramebuffer = st_validate_framebuffer;
-#endif
 
    functions->DrawBuffers = st_DrawBuffers;
    functions->ReadBuffer = st_ReadBuffer;