Viktor Novotný
2012-Jul-06 17:27 UTC
[Nouveau] [PATCH] dri/nouveau: Add AllocTextureImageBuffer() implementation
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