[Mesa-dev] [PATCH 1/8] mesa/st: create interface to verify fb format, reject bad fbs

Ilia Mirkin imirkin at alum.mit.edu
Fri Oct 4 01:34:12 PDT 2013


Extract format parameters in st_validate_framebuffer and call the new
optional pipe->is_fb_format_supported function to check that parameters
are supported by the driver.

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---

I'm a bit weirded out that no attempt is made to check if the att->Type ==
GL_TEXTURE for cbufs, but the check is there for depth. I'm also assuming that
att->Type == GL_RENDERBUFFER_EXT (or GL_NONE) for cbufs, but am still allowing
for the case that depth->Type == GL_TEXTURE. Perhaps one or both of these is
done incorrectly, but I was trying to stay consistent with the assumptions the
current code makes.

 src/gallium/include/pipe/p_screen.h | 18 +++++++++++++++++-
 src/mesa/state_tracker/st_cb_fbo.c  | 27 +++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 3ed7f26..d509d51 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -140,13 +140,29 @@ struct pipe_screen {
                                          enum pipe_video_entrypoint entrypoint );
 
    /**
+    * Check if the given framebuffer configuration is supported. This is used
+    * to reject framebuffers that contain combinations of parameters not
+    * supported by the underlying hardware (e.g. different color formats,
+    * incompatible cbuf/zsbuf settings, etc). If unset, the calling code
+    * should assume that there are no driver-specific restrictions.
+    *
+    * \param num_color_formats  number of entires in the color_formats array
+    * \param color_formats  array of formats corresponding to cbuf surfaces
+    * \param zsformat  format corresponding to the zsbuf surface
+    */
+   boolean (*is_fb_format_supported)( const struct pipe_screen *,
+                                      int num_color_formats,
+                                      const enum pipe_format *color_formats,
+                                      enum pipe_format zsformat);
+
+   /**
     * Check if we can actually create the given resource (test the dimension,
     * overall size, etc).  Used to implement proxy textures.
     * \return TRUE if size is OK, FALSE if too large.
     */
    boolean (*can_create_resource)(struct pipe_screen *screen,
                                   const struct pipe_resource *templat);
-                               
+
    /**
     * Create a new texture object, using the given template info.
     */
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 2089482..04807e7 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -547,6 +547,8 @@ st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
    enum pipe_format first_format = PIPE_FORMAT_NONE;
    boolean mixed_formats =
          screen->get_param(screen, PIPE_CAP_MIXED_COLORBUFFER_FORMATS) != 0;
+   enum pipe_format formats[MAX_DRAW_BUFFERS];
+   int num_formats = 0;
 
    if (depth->Type && stencil->Type && depth->Type != stencil->Type) {
       st_fbo_invalid("Different Depth/Stencil buffer formats");
@@ -595,6 +597,11 @@ st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
 	 return;
       }
 
+      if (att->Type != GL_NONE) {
+         formats[num_formats++] =
+            st_renderbuffer(att->Renderbuffer)->surface->format;
+      }
+
       if (!mixed_formats) {
          /* Disallow mixed formats. */
          if (att->Type != GL_NONE) {
@@ -612,6 +619,26 @@ st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
          }
       }
    }
+
+   if (screen->is_fb_format_supported) {
+      enum pipe_format zsformat;
+      switch (depth->Type) {
+      case GL_RENDERBUFFER_EXT:
+         zsformat = st_renderbuffer(depth->Renderbuffer)->surface->format;
+         break;
+      case GL_TEXTURE:
+         zsformat = st_get_texobj_resource(depth->Texture)->format;
+         break;
+      default:
+         zsformat = PIPE_FORMAT_NONE;
+      }
+      if (!screen->is_fb_format_supported(
+                screen, num_formats, formats, zsformat)) {
+         fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+         st_fbo_invalid("Incompatible color/depth formats");
+         return;
+      }
+   }
 }
 
 
-- 
1.8.1.5



More information about the mesa-dev mailing list