Merge commit 'origin/7.8'
[mesa.git] / src / gallium / drivers / nvfx / nvfx_transfer.c
index 1c250e9fe4494449077f5b2c8fbdd9f5954507ac..59ab14826c354b2ded98f1e2cee06f18aee951d7 100644 (file)
@@ -8,6 +8,8 @@
 #include "nvfx_context.h"
 #include "nvfx_screen.h"
 #include "nvfx_state.h"
+#include "nvfx_resource.h"
+#include "nvfx_transfer.h"
 
 struct nvfx_transfer {
        struct pipe_transfer base;
@@ -16,10 +18,11 @@ struct nvfx_transfer {
 };
 
 static void
-nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
-                             struct pipe_texture *template)
+nvfx_compatible_transfer_tex(struct pipe_resource *pt, unsigned width, unsigned height,
+                            unsigned bind,
+                             struct pipe_resource *template)
 {
-       memset(template, 0, sizeof(struct pipe_texture));
+       memset(template, 0, sizeof(struct pipe_resource));
        template->target = pt->target;
        template->format = pt->format;
        template->width0 = width;
@@ -27,56 +30,77 @@ nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned h
        template->depth0 = 1;
        template->last_level = 0;
        template->nr_samples = pt->nr_samples;
+       template->bind = bind;
+       template->_usage = PIPE_USAGE_DYNAMIC;
+       template->flags = NVFX_RESOURCE_FLAG_LINEAR;
+}
+
+
+static unsigned nvfx_transfer_bind_flags( unsigned transfer_usage )
+{
+       unsigned bind = 0;
+
+       if (transfer_usage & PIPE_TRANSFER_WRITE)
+               bind |= PIPE_BIND_BLIT_DESTINATION;
 
-       template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
-                             NOUVEAU_TEXTURE_USAGE_LINEAR;
+       if (transfer_usage & PIPE_TRANSFER_READ)
+               bind |= PIPE_BIND_BLIT_SOURCE;
+
+       return bind;
 }
 
-static struct pipe_transfer *
-nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt,
-                 unsigned face, unsigned level, unsigned zslice,
-                 enum pipe_transfer_usage usage,
-                 unsigned x, unsigned y, unsigned w, unsigned h)
+struct pipe_transfer *
+nvfx_miptree_transfer_new(struct pipe_context *pipe,
+                         struct pipe_resource *pt,
+                         struct pipe_subresource sr,
+                         unsigned usage,
+                         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_texture tx_tex_template, *tx_tex;
+       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", TRUE/*XXX:FALSE*/);
 
+
        tx = CALLOC_STRUCT(nvfx_transfer);
        if (!tx)
                return NULL;
 
-       pipe_texture_reference(&tx->base.texture, pt);
-       tx->base.x = x;
-       tx->base.y = y;
-       tx->base.width = w;
-       tx->base.height = h;
-       tx->base.stride = mt->level[level].pitch;
+       /* Don't handle 3D transfers yet.
+        */
+       assert(box->depth == 1);
+
+       pipe_resource_reference(&tx->base.resource, pt);
+       tx->base.sr = sr;
        tx->base.usage = usage;
-       tx->base.face = face;
-       tx->base.level = level;
-       tx->base.zslice = zslice;
+       tx->base.box = *box;
+       tx->base.stride = mt->level[sr.level].pitch;
 
        /* Direct access to texture */
-       if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || no_transfer) &&
-           pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
+       if ((pt->_usage == PIPE_USAGE_DYNAMIC ||
+            no_transfer) &&
+           pt->flags & NVFX_RESOURCE_FLAG_LINEAR)
        {
                tx->direct = true;
+
+               /* XXX: just call the internal nvfx function.  
+                */
                tx->surface = pscreen->get_tex_surface(pscreen, pt,
-                                                      face, level, zslice,
-                                                      pipe_transfer_buffer_flags(&tx->base));
+                                                      sr.face, sr.level,
+                                                      box->z,
+                                                      bind);
                return &tx->base;
        }
 
        tx->direct = false;
 
-       nvfx_compatible_transfer_tex(pt, w, h, &tx_tex_template);
+       nvfx_compatible_transfer_tex(pt, box->width, box->height, bind, &tx_tex_template);
 
-       tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
+       tx_tex = pscreen->resource_create(pscreen, &tx_tex_template);
        if (!tx_tex)
        {
                FREE(tx);
@@ -87,9 +111,9 @@ nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt,
 
        tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
                                               0, 0, 0,
-                                              pipe_transfer_buffer_flags(&tx->base));
+                                              bind);
 
-       pipe_texture_reference(&tx_tex, NULL);
+       pipe_resource_reference(&tx_tex, NULL);
 
        if (!tx->surface)
        {
@@ -103,15 +127,16 @@ nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt,
                struct pipe_surface *src;
 
                src = pscreen->get_tex_surface(pscreen, pt,
-                                              face, level, zslice,
-                                              PIPE_BUFFER_USAGE_GPU_READ);
+                                              sr.face, sr.level, box->z,
+                                              PIPE_BIND_BLIT_SOURCE);
 
                /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
                /* TODO: Check if SIFM can un-swizzle */
                nvscreen->eng2d->copy(nvscreen->eng2d,
                                      tx->surface, 0, 0,
-                                     src, x, y,
-                                     w, h);
+                                     src,
+                                     box->x, box->y,
+                                     box->width, box->height);
 
                pipe_surface_reference(&src, NULL);
        }
@@ -119,9 +144,9 @@ nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt,
        return &tx->base;
 }
 
-static void
-nvfx_transfer_del(struct pipe_context *pipe,
-                  struct pipe_transfer *ptx)
+void
+nvfx_miptree_transfer_del(struct pipe_context *pipe,
+                         struct pipe_transfer *ptx)
 {
        struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
 
@@ -130,55 +155,51 @@ nvfx_transfer_del(struct pipe_context *pipe,
                struct nvfx_screen *nvscreen = nvfx_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 | NOUVEAU_BUFFER_USAGE_NO_RENDER);
+               dst = pscreen->get_tex_surface(pscreen,
+                                              ptx->resource,
+                                              ptx->sr.face,
+                                              ptx->sr.level,
+                                              ptx->box.z,
+                                              PIPE_BIND_BLIT_DESTINATION);
 
                /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
                nvscreen->eng2d->copy(nvscreen->eng2d,
-                                     dst, tx->base.x, tx->base.y,
+                                     dst, ptx->box.x, ptx->box.y,
                                      tx->surface, 0, 0,
-                                     tx->base.width, tx->base.height);
+                                     ptx->box.width, ptx->box.height);
 
                pipe_surface_reference(&dst, NULL);
        }
 
        pipe_surface_reference(&tx->surface, NULL);
-       pipe_texture_reference(&ptx->texture, NULL);
+       pipe_resource_reference(&ptx->resource, NULL);
        FREE(ptx);
 }
 
-static void *
-nvfx_transfer_map(struct pipe_context *pipe, struct pipe_transfer *ptx)
+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;
-       void *map = pipe_buffer_map(pscreen, mt->buffer,
-                                   pipe_transfer_buffer_flags(ptx));
+       uint8_t *map = nouveau_screen_bo_map(pscreen, mt->base.bo,
+                                            nouveau_screen_transfer_flags(ptx->usage));
 
        if(!tx->direct)
                return map + ns->base.offset;
        else
-               return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
+               return (map + ns->base.offset + 
+                       ptx->box.y * ns->pitch + 
+                       ptx->box.x * util_format_get_blocksize(ptx->resource->format));
 }
 
-static void
-nvfx_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *ptx)
+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;
 
-       pipe_buffer_unmap(pscreen, mt->buffer);
-}
-
-void
-nvfx_init_transfer_functions(struct nvfx_context *nvfx)
-{
-       nvfx->pipe.get_tex_transfer = nvfx_transfer_new;
-       nvfx->pipe.tex_transfer_destroy = nvfx_transfer_del;
-       nvfx->pipe.transfer_map = nvfx_transfer_map;
-       nvfx->pipe.transfer_unmap = nvfx_transfer_unmap;
+       nouveau_screen_bo_unmap(pscreen, mt->base.bo);
 }