nouveau: Fix nv20-40 swizzled miptree RTs
[mesa.git] / src / gallium / drivers / nv30 / nv30_transfer.c
index 8b915b35bd4c01ff2b7e8477728db5c4480bd167..68047c47ec52f7f64d00d8f22f0a3c786d6147f0 100644 (file)
@@ -1,7 +1,9 @@
 #include <pipe/p_state.h>
 #include <pipe/p_defines.h>
 #include <pipe/p_inlines.h>
+#include <util/u_format.h>
 #include <util/u_memory.h>
+#include <util/u_math.h>
 #include <nouveau/nouveau_winsys.h>
 #include "nv30_context.h"
 #include "nv30_screen.h"
 struct nv30_transfer {
        struct pipe_transfer base;
        struct pipe_surface *surface;
-       bool direct;
+       boolean direct;
 };
 
-static unsigned nv30_usage_tx_to_buf(unsigned tx_usage)
-{
-       switch (tx_usage) {
-               case PIPE_TRANSFER_READ:
-                       return PIPE_BUFFER_USAGE_CPU_READ;
-               case PIPE_TRANSFER_WRITE:
-                       return PIPE_BUFFER_USAGE_CPU_WRITE;
-               case PIPE_TRANSFER_READ_WRITE:
-                       return PIPE_BUFFER_USAGE_CPU_READ_WRITE;
-               default:
-                       assert(0);
-       }
-
-       return -1;
-}
-
 static void
 nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
                              struct pipe_texture *template)
@@ -36,14 +22,10 @@ nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
        memset(template, 0, sizeof(struct pipe_texture));
        template->target = pt->target;
        template->format = pt->format;
-       template->width[0] = pt->width[level];
-       template->height[0] = pt->height[level];
-       template->depth[0] = 1;
-       template->block = pt->block;
-       template->nblocksx[0] = pt->nblocksx[level];
-       template->nblocksy[0] = pt->nblocksx[level];
+       template->width0 = u_minify(pt->width0, level);
+       template->height0 = u_minify(pt->height0, level);
+       template->depth0 = 1;
        template->last_level = 0;
-       template->compressed = pt->compressed;
        template->nr_samples = pt->nr_samples;
 
        template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
@@ -65,14 +47,10 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
                return NULL;
 
        pipe_texture_reference(&tx->base.texture, pt);
-       tx->base.format = pt->format;
        tx->base.x = x;
        tx->base.y = y;
        tx->base.width = w;
        tx->base.height = h;
-       tx->base.block = pt->block;
-       tx->base.nblocksx = pt->nblocksx[level];
-       tx->base.nblocksy = pt->nblocksy[level];
        tx->base.stride = mt->level[level].pitch;
        tx->base.usage = usage;
        tx->base.face = face;
@@ -87,7 +65,7 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
                tx->direct = true;
                tx->surface = pscreen->get_tex_surface(pscreen, pt,
                                                       face, level, zslice,
-                                                      nv30_usage_tx_to_buf(usage));
+                                                      pipe_transfer_buffer_flags(&tx->base));
                return &tx->base;
        }
 
@@ -104,7 +82,7 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
 
        tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
                                               0, 0, 0,
-                                              nv30_usage_tx_to_buf(usage));
+                                              pipe_transfer_buffer_flags(&tx->base));
 
        pipe_texture_reference(&tx_tex, NULL);
 
@@ -115,7 +93,7 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
                return NULL;
        }
 
-       if (usage != PIPE_TRANSFER_WRITE) {
+       if (usage & PIPE_TRANSFER_READ) {
                struct nv30_screen *nvscreen = nv30_screen(pscreen);
                struct pipe_surface *src;
 
@@ -141,14 +119,14 @@ nv30_transfer_del(struct pipe_transfer *ptx)
 {
        struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
 
-       if (!tx->direct && ptx->usage != PIPE_TRANSFER_READ) {
+       if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
                struct pipe_screen *pscreen = ptx->texture->screen;
                struct nv30_screen *nvscreen = nv30_screen(pscreen);
                struct pipe_surface *dst;
 
                dst = pscreen->get_tex_surface(pscreen, ptx->texture,
                                               ptx->face, ptx->level, ptx->zslice,
-                                              PIPE_BUFFER_USAGE_GPU_WRITE);
+                                              PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);
 
                /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
                nvscreen->eng2d->copy(nvscreen->eng2d,
@@ -171,10 +149,10 @@ nv30_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
        struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
        struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture;
        void *map = pipe_buffer_map(pscreen, mt->buffer,
-                                   nv30_usage_tx_to_buf(ptx->usage));
+                                   pipe_transfer_buffer_flags(ptx));
 
        return map + ns->base.offset +
-              ptx->y * ns->pitch + ptx->x * ptx->block.size;
+              ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
 }
 
 static void