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 <[email protected]> --- 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 _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
