[Nouveau] [PATCH] dri/nouveau: Add AllocTextureImageBuffer() implementation

Viktor Novotný noviktor at seznam.cz
Fri Jul 6 10:27:15 PDT 2012


Fixes mipmap generation.

Signed-off-by: Viktor Novotný <noviktor at seznam.cz>
---
Hi,

this fixes bug with mipmaps I observed on nv25, where in _mesa_prepare_mipmap_level call to
Driver.FreeTextureImageBuffer unreferences nouveau_teximage's nouveau_surface, which then
doesnt get reallocated in Driver.AllocTextureImageBuffer, because vieux uses swrast implementation,
ultimately leading to assertion failure in get_rt_format in nv20_buffer_emit.

Apart from adding nouveau_alloc_texture_image_buffer I renamed nouveau_teximage_free.
What I am unsure of is the code concerning swrast_texture_image and the test for early return
in nouveau_alloc_texture_image_buffer. 

	Viktor

 src/mesa/drivers/dri/nouveau/nouveau_texture.c |   71 +++++++++++++++++++-----
 1 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c
index 0060f46..7757b19 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c
@@ -40,6 +40,7 @@
 #include "main/teximage.h"
 #include "drivers/common/meta.h"
 #include "swrast/s_texfetch.h"
+#include "swrast/swrast.h"
 
 static struct gl_texture_object *
 nouveau_texture_new(struct gl_context *ctx, GLuint name, GLenum target)
@@ -71,12 +72,64 @@ nouveau_teximage_new(struct gl_context *ctx)
 	return &nti->base.Base;
 }
 
+static unsigned
+get_teximage_placement(struct gl_texture_image *ti)
+{
+	if (ti->TexFormat == MESA_FORMAT_A8 ||
+	    ti->TexFormat == MESA_FORMAT_L8 ||
+	    ti->TexFormat == MESA_FORMAT_I8)
+		/* 1 cpp formats will have to be swizzled by the CPU,
+		 * so leave them in system RAM for now. */
+		return NOUVEAU_BO_MAP;
+	else
+		return NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
+}
+
+static GLboolean
+nouveau_alloc_texture_image_buffer(struct gl_context *ctx,
+			  struct gl_texture_image *ti,
+			  gl_format format, GLsizei width,
+			  GLsizei height, GLsizei depth)
+{
+	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
+	struct nouveau_surface *s = &nti->surface;
+
+	if (s->bo && s->format == ti->TexFormat &&
+		s->width == ti->Width && s->height == ti->Height &&
+		nti->base.ImageOffsets)
+		/* Image fits on surface, no need to alloc anything */
+			return GL_TRUE;
+
+	ctx->Driver.FreeTextureImageBuffer(ctx, ti);
+
+	assert(!nti->base.ImageOffsets);
+	nti->base.ImageOffsets = malloc(sizeof(GLuint));
+	_swrast_init_texture_image(ti, width, height, depth);
+	
+	nouveau_surface_alloc(ctx, s, LINEAR, get_teximage_placement(ti),
+			  ti->TexFormat, width, height);
+	nti->base.RowStride = s->pitch / s->cpp;
+
+	return GL_TRUE;
+}
+
 static void
-nouveau_teximage_free(struct gl_context *ctx, struct gl_texture_image *ti)
+nouveau_free_texture_image_buffer(struct gl_context *ctx,
+			  struct gl_texture_image *ti)
 {
 	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
 
 	nouveau_surface_ref(NULL, &nti->surface);
+
+	if (nti->base.Buffer) {
+		_mesa_align_free(nti->base.Buffer);
+		nti->base.Buffer = NULL;
+	}
+
+	if (nti->base.ImageOffsets) {
+		free(nti->base.ImageOffsets);
+		nti->base.ImageOffsets = NULL;
+	}
 }
 
 static void
@@ -465,19 +518,6 @@ nouveau_texture_reallocate(struct gl_context *ctx, struct gl_texture_object *t)
 	}
 }
 
-static unsigned
-get_teximage_placement(struct gl_texture_image *ti)
-{
-	if (ti->TexFormat == MESA_FORMAT_A8 ||
-	    ti->TexFormat == MESA_FORMAT_L8 ||
-	    ti->TexFormat == MESA_FORMAT_I8)
-		/* 1 cpp formats will have to be swizzled by the CPU,
-		 * so leave them in system RAM for now. */
-		return NOUVEAU_BO_MAP;
-	else
-		return NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
-}
-
 static void
 nouveau_teximage(struct gl_context *ctx, GLint dims,
 		 struct gl_texture_image *ti,
@@ -704,7 +744,8 @@ nouveau_texture_functions_init(struct dd_function_table *functions)
 	functions->NewTextureObject = nouveau_texture_new;
 	functions->DeleteTexture = nouveau_texture_free;
 	functions->NewTextureImage = nouveau_teximage_new;
-	functions->FreeTextureImageBuffer = nouveau_teximage_free;
+	functions->AllocTextureImageBuffer = nouveau_alloc_texture_image_buffer;
+	functions->FreeTextureImageBuffer = nouveau_free_texture_image_buffer;
 	functions->ChooseTextureFormat = nouveau_choose_tex_format;
 	functions->TexImage = nouveau_teximage_123d;
 	functions->TexSubImage = nouveau_texsubimage_123d;
-- 
1.7.8.6



More information about the Nouveau mailing list