Mesa (master): dri/nouveau: Pipeline glTexSubImage texture transfers.

Francisco Jerez currojerez at kemper.freedesktop.org
Sun Oct 31 01:08:47 UTC 2010


Module: Mesa
Branch: master
Commit: 088145f95086aa640e20b5436854bb68ca3e4934
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=088145f95086aa640e20b5436854bb68ca3e4934

Author: Francisco Jerez <currojerez at riseup.net>
Date:   Fri Oct 29 18:16:08 2010 +0200

dri/nouveau: Pipeline glTexSubImage texture transfers.

---

 src/mesa/drivers/dri/nouveau/nouveau_texture.c |   83 ++++++++++++++++++------
 src/mesa/drivers/dri/nouveau/nouveau_texture.h |    4 +
 2 files changed, 68 insertions(+), 19 deletions(-)

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c
index 9254a9e..060c2c5 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);
-
-		ti->Data = s->bo->map;
+		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);
+
+		} 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 (s->bo)
+	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);
+
+	} 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 fc17021..56e61c7 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))
 




More information about the mesa-commit mailing list