From 126d62edd18f22ff9e744efea81e0383cd0a19c5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 24 Sep 2009 20:03:21 -0700 Subject: [PATCH 1/8] i915: Fix GetBufferSubData in the case of a system-memory BO. Bug #23760 (crashes in wine) --- src/mesa/drivers/dri/intel/intel_buffer_objects.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index 2e6b77824df..db0de0343a8 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -209,7 +209,10 @@ intel_bufferobj_get_subdata(GLcontext * ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - dri_bo_get_subdata(intel_obj->buffer, offset, size, data); + if (intel_obj->sys_buffer) + memcpy(data, (char *)intel_obj->sys_buffer + offset, size); + else + dri_bo_get_subdata(intel_obj->buffer, offset, size, data); } From 151e0c0aeaa78f4eb6a87d2b3dd86b4807db1523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 25 Sep 2009 20:59:44 +0200 Subject: [PATCH 2/8] intel: Handle GL_RGB8 for glCopyTex(Sub)Image. Avoids an unnecessary fallback. --- src/mesa/drivers/dri/intel/intel_tex_copy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 028b49c14d3..74f7f58bbe4 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -74,6 +74,7 @@ get_teximage_source(struct intel_context *intel, GLenum internalFormat) case GL_RGBA: case GL_RGBA8: case GL_RGB: + case GL_RGB8: return intel_readbuf_region(intel); default: return NULL; From 41d0606b7f4666c31db31bec3c54934ef6cd16e7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 25 Sep 2009 17:19:25 -0600 Subject: [PATCH 3/8] gallium/util: add sanity check assertions --- src/gallium/auxiliary/util/u_gen_mipmap.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 833c0b83385..2f24a5a1c97 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -1519,6 +1519,17 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, uint zslice = 0; uint offset; + /* The texture object should have room for the levels which we're + * about to generate. + */ + assert(lastLevel <= pt->last_level); + + /* If this fails, why are we here? */ + assert(lastLevel > baseLevel); + + assert(filter == PIPE_TEX_FILTER_LINEAR || + filter == PIPE_TEX_FILTER_NEAREST); + /* check if we can render in the texture's format */ if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { From e3a6f57ad6c0e7bda5d45eb146194ed39f45abdd Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 28 Sep 2009 09:28:50 -0600 Subject: [PATCH 4/8] st/mesa: fix/simplify st_texture_object::lastLevel calculation Don't compute the st_texture_object::lastLevel field based on the texture filters. Use the _MaxLevel value that core Mesa computes for us. When called from the GenerateMipmap path, we'll use the lastLevel field as-is. --- src/mesa/state_tracker/st_cb_texture.c | 62 ++++---------------------- 1 file changed, 9 insertions(+), 53 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index cfa33d48e12..085da3eab43 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1708,53 +1708,6 @@ st_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, } -/** - * Compute which mipmap levels that really need to be sent to the hardware. - * This depends on the base image size, GL_TEXTURE_MIN_LOD, - * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. - */ -static void -calculate_first_last_level(struct st_texture_object *stObj) -{ - struct gl_texture_object *tObj = &stObj->base; - - /* These must be signed values. MinLod and MaxLod can be negative numbers, - * and having firstLevel and lastLevel as signed prevents the need for - * extra sign checks. - */ - GLint firstLevel; - GLint lastLevel; - - /* Yes, this looks overly complicated, but it's all needed. - */ - switch (tObj->Target) { - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - case GL_TEXTURE_CUBE_MAP: - if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { - /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. - */ - firstLevel = lastLevel = tObj->BaseLevel; - } - else { - firstLevel = 0; - lastLevel = MIN2(tObj->MaxLevel, - (int) tObj->Image[0][tObj->BaseLevel]->WidthLog2); - } - break; - case GL_TEXTURE_RECTANGLE_NV: - case GL_TEXTURE_4D_SGIS: - firstLevel = lastLevel = 0; - break; - default: - return; - } - - stObj->lastLevel = lastLevel; -} - - static void copy_image_data_to_texture(struct st_context *st, struct st_texture_object *stObj, @@ -1818,13 +1771,16 @@ st_finalize_texture(GLcontext *ctx, *needFlush = GL_FALSE; - /* We know/require this is true by now: - */ - assert(stObj->base._Complete); + if (stObj->base._Complete) { + /* The texture is complete and we know exactly how many mipmap levels + * are present/needed. This is conditional because we may be called + * from the st_generate_mipmap() function when the texture object is + * incomplete. In that case, we'll have set stObj->lastLevel before + * we get here. + */ + stObj->lastLevel = stObj->base._MaxLevel - stObj->base.BaseLevel; + } - /* What levels must the texture include at a minimum? - */ - calculate_first_last_level(stObj); firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); /* If both firstImage and stObj point to a texture which can contain From c7fddaf6122da489f4430f6bc2211bcb4740f416 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 25 Sep 2009 17:24:27 -0600 Subject: [PATCH 5/8] st/mesa: fix st_generate_mipmap() issues The main issue is we didn't always have a gallium texture object with enough space to store the to-be-generated mipmap levels. When that's the case, allocate a new gallium texture and use st_texure_finalize() to copy images from the old texture to the new one. We also had the baseLevel parameter to st_render_mipmap() wrong. --- src/mesa/state_tracker/st_gen_mipmap.c | 82 +++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 58f69336523..f75b2348b82 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -27,6 +27,7 @@ #include "main/imports.h" +#include "main/macros.h" #include "main/mipmap.h" #include "main/teximage.h" #include "main/texformat.h" @@ -161,6 +162,43 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, } +/** + * Compute the expected number of mipmap levels in the texture given + * the width/height/depth of the base image and the GL_TEXTURE_BASE_LEVEL/ + * GL_TEXTURE_MAX_LEVEL settings. This will tell us how many mipmap + * level should be generated. + */ +static GLuint +compute_num_levels(GLcontext *ctx, + struct gl_texture_object *texObj, + GLenum target) +{ + if (target == GL_TEXTURE_RECTANGLE_ARB) { + return 1; + } + else { + const GLuint maxLevels = texObj->MaxLevel - texObj->BaseLevel + 1; + const struct gl_texture_image *baseImage = + _mesa_get_tex_image(ctx, texObj, target, texObj->BaseLevel); + GLuint size, numLevels; + + size = MAX2(baseImage->Width2, baseImage->Height2); + size = MAX2(size, baseImage->Depth2); + + numLevels = 0; + + while (size > 0) { + numLevels++; + size >>= 1; + } + + numLevels = MIN2(numLevels, maxLevels); + + return numLevels; + } +} + + void st_generate_mipmap(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj) @@ -174,9 +212,49 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, if (!pt) return; - lastLevel = pt->last_level; + /* find expected last mipmap level */ + lastLevel = compute_num_levels(ctx, texObj, target) - 1; - if (!st_render_mipmap(st, target, pt, baseLevel, lastLevel)) { + if (pt->last_level < lastLevel) { + /* The current gallium texture doesn't have space for all the + * mipmap levels we need to generate. So allocate a new texture. + */ + struct st_texture_object *stObj = st_texture_object(texObj); + struct pipe_texture *oldTex = stObj->pt; + GLboolean needFlush; + + /* create new texture with space for more levels */ + stObj->pt = st_texture_create(st, + oldTex->target, + oldTex->format, + lastLevel, + oldTex->width[0], + oldTex->height[0], + oldTex->depth[0], + oldTex->tex_usage); + + /* The texture isn't in a "complete" state yet so set the expected + * lastLevel here, since it won't get done in st_finalize_texture(). + */ + stObj->lastLevel = lastLevel; + + /* This will copy the old texture's base image into the new texture + * which we just allocated. + */ + st_finalize_texture(ctx, st->pipe, texObj, &needFlush); + + /* release the old tex (will likely be freed too) */ + pipe_texture_reference(&oldTex, NULL); + + pt = stObj->pt; + } + + assert(lastLevel <= pt->last_level); + + /* Recall that the Mesa BaseLevel image is stored in the gallium + * texture's level[0] position. So pass baseLevel=0 here. + */ + if (!st_render_mipmap(st, target, pt, 0, lastLevel)) { fallback_generate_mipmap(ctx, target, texObj); } From c7d0f0b46c16de1ae575446f2471cf297acacb29 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 28 Sep 2009 09:38:50 -0600 Subject: [PATCH 6/8] docs: document gallium mipmap generation fix --- docs/relnotes-7.5.2.html | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/relnotes-7.5.2.html b/docs/relnotes-7.5.2.html index b638c0517dd..40b4ae85ef9 100644 --- a/docs/relnotes-7.5.2.html +++ b/docs/relnotes-7.5.2.html @@ -49,6 +49,7 @@ tbd (such as bug 23946)
  • glUseProgram() is now compiled into display lists (bug 23746).
  • glUniform functions are now compiled into display lists +
  • Auto mipmap generation didn't work reliably with Gallium. From fc613848e6f8f1c5405a7612b00a02ac2a794b80 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 28 Sep 2009 09:43:42 -0600 Subject: [PATCH 7/8] docs: list additional 7.5.2 bug fixes --- docs/relnotes-7.5.2.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/relnotes-7.5.2.html b/docs/relnotes-7.5.2.html index 40b4ae85ef9..0832e11bb49 100644 --- a/docs/relnotes-7.5.2.html +++ b/docs/relnotes-7.5.2.html @@ -50,6 +50,9 @@ tbd
  • glUseProgram() is now compiled into display lists (bug 23746).
  • glUniform functions are now compiled into display lists
  • Auto mipmap generation didn't work reliably with Gallium. +
  • Fixed random number usage in GLX code. +
  • Fixed invalid GL_OUT_OF_MEMORY error sometimes raised by glTexSubImage2D + when using Gallium. From d09941c8cc2d4620eb774744c8878921b9dc3bcc Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Tue, 22 Sep 2009 11:49:57 -0700 Subject: [PATCH 8/8] Fix build on non GLIBC platforms (FreeBSD at least) Build was broken by commit 9666529b5a5be1fcde82caadc2fe2efa5ea81e49 I'm not certain that this is entirely the correct fix since the demo from bug #23774 seemed to work before the commit that broke the build. Signed-off-by: Robert Noland Signed-off-by: Brian Paul --- src/glx/x11/glxhash.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/glx/x11/glxhash.c b/src/glx/x11/glxhash.c index 6f2c51d39dd..b76ec323459 100644 --- a/src/glx/x11/glxhash.c +++ b/src/glx/x11/glxhash.c @@ -88,6 +88,12 @@ #define HASH_ALLOC malloc #define HASH_FREE free +#ifndef __GLIBC__ +#define HASH_RANDOM_DECL char *ps, rs[256] +#define HASH_RANDOM_INIT(seed) ps = initstate(seed, rs, sizeof(rs)) +#define HASH_RANDOM random() +#define HASH_RANDOM_DESTROY setstate(ps) +#else #define HASH_RANDOM_DECL struct random_data rd; int32_t rv; char rs[256] #define HASH_RANDOM_INIT(seed) \ do { \ @@ -96,6 +102,7 @@ } while(0) #define HASH_RANDOM ((void) random_r(&rd, &rv), rv) #define HASH_RANDOM_DESTROY +#endif typedef struct __glxHashBucket {