diff options
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_texture.c | 81 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_texture.h | 4 | 
2 files changed, 67 insertions, 18 deletions
| diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c index 9254a9e7be..060c2c5bcc 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c @@ -79,26 +79,65 @@ nouveau_teximage_free(struct gl_context *ctx, struct gl_texture_image *ti)  }  static void -nouveau_teximage_map(struct gl_context *ctx, struct gl_texture_image *ti) +nouveau_teximage_map(struct gl_context *ctx, struct gl_texture_image *ti, +		     int access, int x, int y, int w, int h)  { -	struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; -	int ret; +	struct nouveau_teximage *nti = to_nouveau_teximage(ti); +	struct nouveau_surface *s = &nti->surface; +	struct nouveau_surface *st = &nti->transfer.surface;  	if (s->bo) { -		ret = nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR); -		assert(!ret); +		if (!(access & GL_MAP_READ_BIT) && +		    nouveau_bo_pending(s->bo)) { +			/* +			 * Heuristic: use a bounce buffer to pipeline +			 * teximage transfers. +			 */ +			st->layout = LINEAR; +			st->format = s->format; +			st->cpp = s->cpp; +			st->width = w; +			st->height = h; +			st->pitch = s->pitch; +			nti->transfer.x = x; +			nti->transfer.y = y; + +			ti->Data = nouveau_get_scratch(ctx, st->pitch * h, +						       &st->bo, &st->offset); -		ti->Data = s->bo->map; +		} else { +			int ret, flags = 0; + +			if (access & GL_MAP_READ_BIT) +				flags |= NOUVEAU_BO_RD; +			if (access & GL_MAP_WRITE_BIT) +				flags |= NOUVEAU_BO_WR; + +			ret = nouveau_bo_map(s->bo, flags); +			assert(!ret); + +			ti->Data = s->bo->map + y * s->pitch + x * s->cpp; +		}  	}  }  static void  nouveau_teximage_unmap(struct gl_context *ctx, struct gl_texture_image *ti)  { -	struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; +	struct nouveau_teximage *nti = to_nouveau_teximage(ti); +	struct nouveau_surface *s = &nti->surface; +	struct nouveau_surface *st = &nti->transfer.surface; + +	if (st->bo) { +		context_drv(ctx)->surface_copy(ctx, s, st, nti->transfer.x, +					       nti->transfer.y, 0, 0, +					       st->width, st->height); +		nouveau_surface_ref(NULL, st); -	if (s->bo) +	} else if (s->bo) {  		nouveau_bo_unmap(s->bo); +	} +  	ti->Data = NULL;  } @@ -361,7 +400,8 @@ nouveau_teximage(struct gl_context *ctx, GLint dims, GLenum target, GLint level,  					     "glTexImage");  	if (pixels) {  		/* Store the pixel data. */ -		nouveau_teximage_map(ctx, ti); +		nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT, +				     0, 0, width, height);  		ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,  				     ti->TexFormat, ti->Data, @@ -448,13 +488,13 @@ nouveau_texsubimage(struct gl_context *ctx, GLint dims, GLenum target, GLint lev  					     format, type, pixels, packing,  					     "glTexSubImage");  	if (pixels) { -		nouveau_teximage_map(ctx, ti); +		nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT, +				     xoffset, yoffset, width, height);  		ret = _mesa_texstore(ctx, 3, ti->_BaseFormat, ti->TexFormat, -				     ti->Data, xoffset, yoffset, zoffset, -				     s->pitch, ti->ImageOffsets, -				     width, height, depth, format, type, -				     pixels, packing); +				     ti->Data, 0, 0, 0, s->pitch, +				     ti->ImageOffsets, width, height, depth, +				     format, type, pixels, packing);  		assert(ret);  		nouveau_teximage_unmap(ctx, ti); @@ -513,7 +553,8 @@ nouveau_get_teximage(struct gl_context *ctx, GLenum target, GLint level,  		     struct gl_texture_object *t,  		     struct gl_texture_image *ti)  { -	nouveau_teximage_map(ctx, ti); +	nouveau_teximage_map(ctx, ti, GL_MAP_READ_BIT, +			     0, 0, ti->Width, ti->Height);  	_mesa_get_teximage(ctx, target, level, format, type, pixels,  			   t, ti);  	nouveau_teximage_unmap(ctx, ti); @@ -584,8 +625,11 @@ nouveau_texture_map(struct gl_context *ctx, struct gl_texture_object *t)  	int i;  	for (i = t->BaseLevel; i < t->_MaxLevel; i++) { -		if (t->Image[0][i]) -			nouveau_teximage_map(ctx, t->Image[0][i]); +		struct gl_texture_image *ti = t->Image[0][i]; + +		if (ti) +			nouveau_teximage_map(ctx, ti, GL_MAP_READ_BIT, +					     0, 0, ti->Width, ti->Height);  	}  } @@ -635,7 +679,8 @@ nouveau_generate_mipmap(struct gl_context *ctx, GLenum target,  	if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, t)) {  		struct gl_texture_image *base = t->Image[0][t->BaseLevel]; -		nouveau_teximage_map(ctx, base); +		nouveau_teximage_map(ctx, base, GL_MAP_READ_BIT, +				     0, 0, base->Width, base->Height);  		_mesa_generate_mipmap(ctx, target, t);  		nouveau_teximage_unmap(ctx, base); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.h b/src/mesa/drivers/dri/nouveau/nouveau_texture.h index fc170215f3..56e61c7337 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_texture.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.h @@ -30,6 +30,10 @@  struct nouveau_teximage {  	struct gl_texture_image base;  	struct nouveau_surface surface; +	struct { +		struct nouveau_surface surface; +		int x, y; +	} transfer;  };  #define to_nouveau_teximage(x) ((struct nouveau_teximage *)(x)) | 
