nvfx: new 2D: rewrite miptree code, adapt transfers
[mesa.git] / src / gallium / drivers / nvfx / nvfx_transfer.c
index a776ab58311d877298ed1815df00aa5d858b9f19..957e586f81d90de9c7f7ff2e48179d0473962188 100644 (file)
@@ -31,7 +31,7 @@ nvfx_compatible_transfer_tex(struct pipe_resource *pt, unsigned width, unsigned
        template->last_level = 0;
        template->nr_samples = pt->nr_samples;
        template->bind = bind;
-       template->_usage = PIPE_USAGE_DYNAMIC;
+       template->usage = PIPE_USAGE_DYNAMIC;
        template->flags = NVFX_RESOURCE_FLAG_LINEAR;
 }
 
@@ -40,11 +40,13 @@ static unsigned nvfx_transfer_bind_flags( unsigned transfer_usage )
 {
        unsigned bind = 0;
 
+#if 0
        if (transfer_usage & PIPE_TRANSFER_WRITE)
                bind |= PIPE_BIND_BLIT_SOURCE;
 
        if (transfer_usage & PIPE_TRANSFER_READ)
                bind |= PIPE_BIND_BLIT_DESTINATION;
+#endif
 
        return bind;
 }
@@ -57,14 +59,9 @@ nvfx_miptree_transfer_new(struct pipe_context *pipe,
                          const struct pipe_box *box)
 {
        struct pipe_screen *pscreen = pipe->screen;
-       struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
        struct nvfx_transfer *tx;
        struct pipe_resource tx_tex_template, *tx_tex;
-       static int no_transfer = -1;
        unsigned bind = nvfx_transfer_bind_flags(usage);
-       if(no_transfer < 0)
-               no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER", FALSE);
-
 
        tx = CALLOC_STRUCT(nvfx_transfer);
        if (!tx)
@@ -76,13 +73,13 @@ nvfx_miptree_transfer_new(struct pipe_context *pipe,
 
        pipe_resource_reference(&tx->base.resource, pt);
        tx->base.sr = sr;
+       tx->base.stride = nvfx_subresource_pitch(pt, sr.level);
+       tx->base.slice_stride = tx->base.stride * u_minify(pt->height0, sr.level);
        tx->base.usage = usage;
        tx->base.box = *box;
-       tx->base.stride = mt->level[sr.level].pitch;
 
        /* Direct access to texture */
-       if ((pt->_usage == PIPE_USAGE_DYNAMIC ||
-            no_transfer) &&
+       if ((util_format_is_s3tc(pt->format) || pt->usage & PIPE_USAGE_DYNAMIC) &&
            pt->flags & NVFX_RESOURCE_FLAG_LINEAR)
        {
                tx->direct = true;
@@ -107,7 +104,8 @@ nvfx_miptree_transfer_new(struct pipe_context *pipe,
                return NULL;
        }
 
-       tx->base.stride = ((struct nvfx_miptree*)tx_tex)->level[0].pitch;
+       tx->base.stride = ((struct nvfx_miptree*)tx_tex)->linear_pitch;
+       tx->base.slice_stride = tx->base.stride * box->height;
 
        tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
                                               0, 0, 0,
@@ -128,7 +126,7 @@ nvfx_miptree_transfer_new(struct pipe_context *pipe,
 
                src = pscreen->get_tex_surface(pscreen, pt,
                                               sr.face, sr.level, box->z,
-                                              PIPE_BIND_BLIT_SOURCE);
+                                              0 /*PIPE_BIND_BLIT_SOURCE*/);
 
                /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
                /* TODO: Check if SIFM can un-swizzle */
@@ -160,7 +158,7 @@ nvfx_miptree_transfer_del(struct pipe_context *pipe,
                                               ptx->sr.face,
                                               ptx->sr.level,
                                               ptx->box.z,
-                                              PIPE_BIND_BLIT_DESTINATION);
+                                              0 /*PIPE_BIND_BLIT_DESTINATION*/);
 
                /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
                nvscreen->eng2d->copy(nvscreen->eng2d,
@@ -179,27 +177,26 @@ nvfx_miptree_transfer_del(struct pipe_context *pipe,
 void *
 nvfx_miptree_transfer_map(struct pipe_context *pipe, struct pipe_transfer *ptx)
 {
-       struct pipe_screen *pscreen = pipe->screen;
        struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
        struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
        struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
-       uint8_t *map = nouveau_screen_bo_map(pscreen, mt->base.bo,
+
+       uint8_t *map = nouveau_screen_bo_map(pipe->screen, mt->base.bo,
                                             nouveau_screen_transfer_flags(ptx->usage));
 
        if(!tx->direct)
                return map + ns->base.offset;
        else
-               return (map + ns->base.offset + 
-                       ptx->box.y * ns->pitch + 
-                       ptx->box.x * util_format_get_blocksize(ptx->resource->format));
+               return map + ns->base.offset
+               + util_format_get_2d_size(ns->base.format, ns->pitch, ptx->box.y)
+               + util_format_get_stride(ptx->resource->format, ptx->box.x);
 }
 
 void
 nvfx_miptree_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *ptx)
 {
-       struct pipe_screen *pscreen = pipe->screen;
        struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
        struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
 
-       nouveau_screen_bo_unmap(pscreen, mt->base.bo);
+       nouveau_screen_bo_unmap(pipe->screen, mt->base.bo);
 }