nv50: quick hack to get textures untiled on map, and tiled on unmap
authorBen Skeggs <skeggsb@gmail.com>
Fri, 11 Jul 2008 12:45:11 +0000 (22:45 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Fri, 11 Jul 2008 12:46:07 +0000 (22:46 +1000)
progs/fp/tri-tex is all good now rather than all scrambled :)

src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_miptree.c
src/gallium/drivers/nv50/nv50_surface.c

index cb51fb02ebde9015dfec0dc37e02c5d87451784e..1c069f1625f7908ca5fd83098a58fe93893bc846 100644 (file)
@@ -74,6 +74,17 @@ nv50_miptree(struct pipe_texture *pt)
        return (struct nv50_miptree *)pt;
 }
 
+struct nv50_surface {
+       struct pipe_surface base;
+       struct pipe_buffer *untiled;
+};
+
+static INLINE struct nv50_surface *
+nv50_surface(struct pipe_surface *pt)
+{
+       return (struct nv50_surface *)pt;
+}
+
 struct nv50_state {
        unsigned dirty;
 
index 8b61ca2a1fa50ff8878078fa4fabf9c985a93eca..a02ad41885ba99935da161cbe4439e57c8876b8a 100644 (file)
@@ -82,9 +82,14 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
 {
        struct pipe_winsys *ws = pscreen->winsys;
        struct nv50_miptree *mt = nv50_miptree(pt);
+       struct nv50_surface *s;
        struct pipe_surface *ps;
 
-       ps = CALLOC_STRUCT(pipe_surface);
+       s = CALLOC_STRUCT(nv50_surface);
+       if (!s)
+               return NULL;
+       ps = &s->base;
+
        ps->refcount = 1;
        ps->winsys = ws;
        ps->format = pt->format;
@@ -109,14 +114,15 @@ nv50_miptree_surface_del(struct pipe_screen *pscreen,
                         struct pipe_surface **psurface)
 {
        struct pipe_winsys *ws = pscreen->winsys;
-       struct pipe_surface *surf = *psurface;
+       struct pipe_surface *ps = *psurface;
+       struct nv50_surface *s = nv50_surface(ps);
 
        *psurface = NULL;
 
-       if (--surf->refcount <= 0) {
-               pipe_texture_reference(&surf->texture, NULL);
-               pipe_buffer_reference(ws, &surf->buffer, NULL);
-               FREE(surf);
+       if (--ps->refcount <= 0) {
+               pipe_texture_reference(&ps->texture, NULL);
+               pipe_buffer_reference(ws, &ps->buffer, NULL);
+               FREE(s);
        }
 }
 
index 6229b63626017e85036794e826ee809c15e57504..8d3f1edcfe958e9e3fd83bb41b61c45ff9866633 100644 (file)
@@ -52,25 +52,51 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
 }
 
 static void *
-nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
+nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *ps,
                 unsigned flags )
 {
+       struct nouveau_winsys *nvws = nv50_screen(screen)->nvws;
        struct pipe_winsys *ws = screen->winsys;
+       struct nv50_surface *s = nv50_surface(ps);
+       struct nv50_surface m = *s;
        void *map;
 
-       map = ws->buffer_map(ws, surface->buffer, flags);
+       if (!s->untiled) {
+               s->untiled = ws->buffer_create(ws, 0, 0, ps->buffer->size);
+
+               m.base.buffer = s->untiled;
+               nvws->surface_copy(nvws, &m.base, 0, 0, &s->base, 0, 0,
+                                        ps->width, ps->height);
+       }
+
+       /* Map original tiled surface to disallow it being validated while
+        * untiled mirror is mapped.
+        */
+       ws->buffer_map(ws, ps->buffer, flags);
+
+       map = ws->buffer_map(ws, s->untiled, flags);
        if (!map)
                return NULL;
 
-       return map + surface->offset;
+       return map;
 }
 
 static void
-nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
+nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *ps)
 {
+       struct nouveau_winsys *nvws = nv50_screen(screen)->nvws;
        struct pipe_winsys *ws = screen->winsys;
+       struct nv50_surface *s = nv50_surface(ps);
+       struct nv50_surface m = *s;
+
+       ws->buffer_unmap(ws, s->untiled);
+       ws->buffer_unmap(ws, ps->buffer);
+
+       m.base.buffer = s->untiled;
+       nvws->surface_copy(nvws, &s->base, 0, 0, &m.base, 0, 0,
+                                ps->width, ps->height);
 
-       ws->buffer_unmap(ws, surface->buffer);
+       pipe_buffer_reference(ws, &s->untiled, NULL);
 }
 
 void