[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