diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_texture.c | 83 | ||||
-rw-r--r-- | 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 9254a9e7bec..060c2c5bcc0 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 fc170215f35..56e61c7337b 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)) |