[Nouveau] [PATCH] nouveau: add framebuffer validation callback
Ilia Mirkin
imirkin at alum.mit.edu
Fri Jan 10 11:11:47 PST 2014
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 <imirkin at alum.mit.edu>
---
In a perfect world I'd have separate callbacks for depth and color, but given
the list of supported values, I don't think this matters. Also I used
st_validate_framebuffer as a template, but I don't know if there can actually
be many attachments. Should MaxColorAttachments be set to 1? I think it's set
to 8 right now.
And there's also an odd nouveau_validate_framebuffer thing in
nouveau_context.c, but I think that's related to actually
rendering/invalidating the fb displayed to the screen.
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
More information about the Nouveau
mailing list