From 767650300c6cc2ec0ac7aa26940e2e3f5a497104 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Fri, 10 Jan 2014 03:02:52 -0500 Subject: [PATCH] nouveau: add framebuffer validation callback Fixes assertions when trying to attach textures to fbs with formats not supported by the render engines. See https://bugs.freedesktop.org/show_bug.cgi?id=73459 Signed-off-by: Ilia Mirkin --- src/mesa/drivers/dri/nouveau/nouveau_driver.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_fbo.c | 38 +++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv04_context.c | 14 ++++++++++ src/mesa/drivers/dri/nouveau/nv10_context.c | 16 +++++++++++ src/mesa/drivers/dri/nouveau/nv20_context.c | 16 +++++++++++ 5 files changed, 85 insertions(+) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/src/mesa/drivers/dri/nouveau/nouveau_driver.h index e03b2c1..84953da 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.h @@ -60,6 +60,7 @@ struct nouveau_driver { struct nouveau_surface *dst, unsigned mask, unsigned value, int dx, int dy, int w, int h); + bool (*is_rt_format_supported)(gl_format format); nouveau_state_func *emit; int num_emit; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c index 25543e4..fba0d52 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -268,6 +268,43 @@ nouveau_finish_render_texture(struct gl_context *ctx, texture_dirty(rb->TexImage->TexObject); } +static void +nouveau_framebuffer_validate(struct gl_context *ctx, + struct gl_framebuffer *fb) +{ + const struct nouveau_driver *drv = context_drv(ctx); + int i, count = 0; + + for (i = 0; i < ctx->Const.MaxColorAttachments; i++) { + struct gl_renderbuffer_attachment *rba = + &fb->Attachment[BUFFER_COLOR0 + i]; + if (rba->Type == GL_NONE) + continue; + + count++; + if (rba->Type != GL_TEXTURE) + continue; + + if (!drv->is_rt_format_supported( + rba->Renderbuffer->TexImage->TexFormat)) + goto err; + } + if (count > 1) + goto err; + + if (fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE) { + struct gl_texture_image *ti = + fb->Attachment[BUFFER_DEPTH].Renderbuffer->TexImage; + if (!drv->is_rt_format_supported(ti->TexFormat)) + goto err; + } + + return; +err: + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; +} + void nouveau_fbo_functions_init(struct dd_function_table *functions) { @@ -279,4 +316,5 @@ nouveau_fbo_functions_init(struct dd_function_table *functions) functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer; functions->RenderTexture = nouveau_render_texture; functions->FinishRenderTexture = nouveau_finish_render_texture; + functions->ValidateFramebuffer = nouveau_framebuffer_validate; } diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.c b/src/mesa/drivers/dri/nouveau/nv04_context.c index c198c03..665cadd 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_context.c +++ b/src/mesa/drivers/dri/nouveau/nv04_context.c @@ -199,11 +199,25 @@ fail: return NULL; } +static bool +nv04_is_rt_format_supported(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_RGB565: + return true; + default: + return false; + } +} + const struct nouveau_driver nv04_driver = { .context_create = nv04_context_create, .context_destroy = nv04_context_destroy, .surface_copy = nv04_surface_copy, .surface_fill = nv04_surface_fill, + .is_rt_format_supported = nv04_is_rt_format_supported, .emit = (nouveau_state_func[]) { nv04_defer_control, nouveau_emit_nothing, diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c index 1918f12..9c5cfcb 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_context.c +++ b/src/mesa/drivers/dri/nouveau/nv10_context.c @@ -492,11 +492,27 @@ fail: return NULL; } +static bool +nv10_is_rt_format_supported(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_Z16: + case MESA_FORMAT_Z24_S8: + return true; + default: + return false; + } +} + const struct nouveau_driver nv10_driver = { .context_create = nv10_context_create, .context_destroy = nv10_context_destroy, .surface_copy = nv04_surface_copy, .surface_fill = nv04_surface_fill, + .is_rt_format_supported = nv10_is_rt_format_supported, .emit = (nouveau_state_func[]) { nv10_emit_alpha_func, nv10_emit_blend_color, diff --git a/src/mesa/drivers/dri/nouveau/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_context.c index 1d77132..e233025 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_context.c +++ b/src/mesa/drivers/dri/nouveau/nv20_context.c @@ -500,11 +500,27 @@ fail: return NULL; } +static bool +nv20_is_rt_format_supported(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_Z16: + case MESA_FORMAT_Z24_S8: + return true; + default: + return false; + } +} + const struct nouveau_driver nv20_driver = { .context_create = nv20_context_create, .context_destroy = nv20_context_destroy, .surface_copy = nv04_surface_copy, .surface_fill = nv04_surface_fill, + .is_rt_format_supported = nv20_is_rt_format_supported, .emit = (nouveau_state_func[]) { nv10_emit_alpha_func, nv10_emit_blend_color, -- 1.8.3.2