Module: Mesa
Branch: master
Commit: 8e1dd58a7e76834c1fb6d117b6ea5755e05cfb77
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=8e1dd58a7e76834c1fb6d117b6ea5755e05cfb77

Author: Christoph Bumiller <e0425...@student.tuwien.ac.at>
Date:   Wed Apr  3 00:18:55 2013 +0200

nvc0: place staging textures in GART and map them directly

---

 src/gallium/drivers/nv50/nv50_miptree.c  |    6 ++--
 src/gallium/drivers/nv50/nv50_resource.h |    2 +-
 src/gallium/drivers/nvc0/nvc0_2d.xml.h   |    2 +-
 src/gallium/drivers/nvc0/nvc0_miptree.c  |   25 ++++++++++++---
 src/gallium/drivers/nvc0/nvc0_screen.c   |    2 +
 src/gallium/drivers/nvc0/nvc0_surface.c  |    3 +-
 src/gallium/drivers/nvc0/nvc0_transfer.c |   47 ++++++++++++++++++++++++++++++
 7 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/nv50/nv50_miptree.c 
b/src/gallium/drivers/nv50/nv50_miptree.c
index ed0f8c2..fe48188 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -213,7 +213,7 @@ nv50_miptree_init_ms_mode(struct nv50_miptree *mt)
 }
 
 boolean
-nv50_miptree_init_layout_linear(struct nv50_miptree *mt)
+nv50_miptree_init_layout_linear(struct nv50_miptree *mt, unsigned pitch_align)
 {
    struct pipe_resource *pt = &mt->base.base;
    const unsigned blocksize = util_format_get_blocksize(pt->format);
@@ -227,7 +227,7 @@ nv50_miptree_init_layout_linear(struct nv50_miptree *mt)
    if (mt->ms_x | mt->ms_y)
       return FALSE;
 
-   mt->level[0].pitch = align(pt->width0 * blocksize, 64);
+   mt->level[0].pitch = align(pt->width0 * blocksize, pitch_align);
 
    /* Account for very generous prefetch (allocate size as if tiled). */
    h = MAX2(h, 8);
@@ -314,7 +314,7 @@ nv50_miptree_create(struct pipe_screen *pscreen,
    if (bo_config.nv50.memtype != 0) {
       nv50_miptree_init_layout_tiled(mt);
    } else
-   if (!nv50_miptree_init_layout_linear(mt)) {
+   if (!nv50_miptree_init_layout_linear(mt, 64)) {
       FREE(mt);
       return NULL;
    }
diff --git a/src/gallium/drivers/nv50/nv50_resource.h 
b/src/gallium/drivers/nv50/nv50_resource.h
index a2bc980..469d812 100644
--- a/src/gallium/drivers/nv50/nv50_resource.h
+++ b/src/gallium/drivers/nv50/nv50_resource.h
@@ -67,7 +67,7 @@ nv50_miptree(struct pipe_resource *pt)
 /* Internal functions:
  */
 boolean
-nv50_miptree_init_layout_linear(struct nv50_miptree *mt);
+nv50_miptree_init_layout_linear(struct nv50_miptree *mt, unsigned pitch_align);
 
 struct pipe_resource *
 nv50_miptree_create(struct pipe_screen *pscreen,
diff --git a/src/gallium/drivers/nvc0/nvc0_2d.xml.h 
b/src/gallium/drivers/nvc0/nvc0_2d.xml.h
index 93dba34..9a488c1 100644
--- a/src/gallium/drivers/nvc0/nvc0_2d.xml.h
+++ b/src/gallium/drivers/nvc0/nvc0_2d.xml.h
@@ -122,7 +122,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.
 
 #define NVC0_2D_UNK258                                         0x00000258
 
-#define NVC0_2D_UNK260                                         0x00000260
+#define NVC0_2D_SINGLE_GPC                                     0x00000260
 
 #define NVC0_2D_COND_ADDRESS_HIGH                              0x00000264
 
diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c 
b/src/gallium/drivers/nvc0/nvc0_miptree.c
index 9fcd788..2913363 100644
--- a/src/gallium/drivers/nvc0/nvc0_miptree.c
+++ b/src/gallium/drivers/nvc0/nvc0_miptree.c
@@ -158,9 +158,6 @@ nvc0_miptree_init_ms_mode(struct nv50_miptree *mt)
    return TRUE;
 }
 
-boolean
-nv50_miptree_init_layout_linear(struct nv50_miptree *);
-
 static void
 nvc0_miptree_init_layout_video(struct nv50_miptree *mt)
 {
@@ -260,6 +257,21 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
    pipe_reference_init(&pt->reference, 1);
    pt->screen = pscreen;
 
+   if (pt->usage == PIPE_USAGE_STAGING) {
+      switch (pt->target) {
+      case PIPE_TEXTURE_1D:
+      case PIPE_TEXTURE_2D:
+      case PIPE_TEXTURE_RECT:
+         if (pt->last_level == 0 &&
+             !util_format_is_depth_or_stencil(pt->format) &&
+             pt->nr_samples <= 1)
+            pt->flags |= NOUVEAU_RESOURCE_FLAG_LINEAR;
+         break;
+      default:
+         break;
+      }
+   }
+
    bo_config.nvc0.memtype = nvc0_mt_choose_storage_type(mt, compressed);
 
    if (!nvc0_miptree_init_ms_mode(mt)) {
@@ -273,13 +285,16 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
    if (likely(bo_config.nvc0.memtype)) {
       nvc0_miptree_init_layout_tiled(mt);
    } else
-   if (!nv50_miptree_init_layout_linear(mt)) {
+   if (!nv50_miptree_init_layout_linear(mt, 128)) {
       FREE(mt);
       return NULL;
    }
    bo_config.nvc0.tile_mode = mt->level[0].tile_mode;
 
-   mt->base.domain = NOUVEAU_BO_VRAM;
+   if (!bo_config.nvc0.memtype && pt->usage == PIPE_USAGE_STAGING)
+      mt->base.domain = NOUVEAU_BO_GART;
+   else
+      mt->base.domain = NOUVEAU_BO_VRAM;
 
    bo_flags = mt->base.domain | NOUVEAU_BO_NOSNOOP;
 
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c 
b/src/gallium/drivers/nvc0/nvc0_screen.c
index 3a32539..a46fb38 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -629,6 +629,8 @@ nvc0_screen_create(struct nouveau_device *dev)
 
    BEGIN_NVC0(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
    PUSH_DATA (push, screen->eng2d->oclass);
+   BEGIN_NVC0(push, NVC0_2D(SINGLE_GPC), 1);
+   PUSH_DATA (push, 0);
    BEGIN_NVC0(push, NVC0_2D(OPERATION), 1);
    PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY);
    BEGIN_NVC0(push, NVC0_2D(CLIP_ENABLE), 1);
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c 
b/src/gallium/drivers/nvc0/nvc0_surface.c
index 481b451..3abf717 100644
--- a/src/gallium/drivers/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nvc0/nvc0_surface.c
@@ -1108,7 +1108,8 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct 
pipe_blit_info *info)
          PUSH_DATA (push, srcy >> 32);
       }
    }
-   nvc0_bufctx_fence(nvc0, nvc0->bufctx, FALSE);
+   nvc0_resource_validate(&dst->base, NOUVEAU_BO_WR);
+   nvc0_resource_validate(&src->base, NOUVEAU_BO_RD);
 
    nouveau_bufctx_reset(nvc0->bufctx, NVC0_BIND_2D);
 
diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c 
b/src/gallium/drivers/nvc0/nvc0_transfer.c
index bdba83d..3f87662 100644
--- a/src/gallium/drivers/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nvc0/nvc0_transfer.c
@@ -328,6 +328,30 @@ nve4_m2mf_copy_linear(struct nouveau_context *nv,
    nouveau_bufctx_reset(bctx, 0);
 }
 
+
+static INLINE boolean
+nvc0_mt_transfer_can_map_directly(struct nv50_miptree *mt)
+{
+   if (mt->base.domain == NOUVEAU_BO_VRAM)
+      return FALSE;
+   if (mt->base.base.usage != PIPE_USAGE_STAGING)
+      return FALSE;
+   return !nouveau_bo_memtype(mt->base.bo);
+}
+
+static INLINE boolean
+nvc0_mt_sync(struct nvc0_context *nvc0, struct nv50_miptree *mt, unsigned 
usage)
+{
+   if (!mt->base.mm) {
+      uint32_t access = (usage & PIPE_TRANSFER_WRITE) ?
+         NOUVEAU_BO_WR : NOUVEAU_BO_RD;
+      return !nouveau_bo_wait(mt->base.bo, access, nvc0->base.client);
+   }
+   if (usage & PIPE_TRANSFER_WRITE)
+      return !mt->base.fence || nouveau_fence_wait(mt->base.fence);
+   return !mt->base.fence_wr || nouveau_fence_wait(mt->base.fence_wr);
+}
+
 void *
 nvc0_miptree_transfer_map(struct pipe_context *pctx,
                           struct pipe_resource *res,
@@ -344,6 +368,16 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx,
    int ret;
    unsigned flags = 0;
 
+   if (nvc0_mt_transfer_can_map_directly(mt)) {
+      ret = !nvc0_mt_sync(nvc0, mt, usage);
+      if (!ret)
+         ret = nouveau_bo_map(mt->base.bo, 0, NULL);
+      if (ret &&
+          (usage & PIPE_TRANSFER_MAP_DIRECTLY))
+         return NULL;
+      if (!ret)
+         usage |= PIPE_TRANSFER_MAP_DIRECTLY;
+   } else
    if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
       return NULL;
 
@@ -369,6 +403,12 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx,
    tx->base.stride = tx->nblocksx * util_format_get_blocksize(res->format);
    tx->base.layer_stride = tx->nblocksy * tx->base.stride;
 
+   if (usage & PIPE_TRANSFER_MAP_DIRECTLY) {
+      tx->base.stride = align(tx->base.stride, 128);
+      *ptransfer = &tx->base;
+      return mt->base.bo->map + mt->base.offset;
+   }
+
    nv50_m2mf_rect_setup(&tx->rect[0], res, level, box->x, box->y, box->z);
 
    size = tx->base.layer_stride;
@@ -437,6 +477,13 @@ nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
    struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
    unsigned i;
 
+   if (tx->base.usage & PIPE_TRANSFER_MAP_DIRECTLY) {
+      pipe_resource_reference(&transfer->resource, NULL);
+
+      FREE(tx);
+      return;
+   }
+
    if (tx->base.usage & PIPE_TRANSFER_WRITE) {
       for (i = 0; i < tx->nlayers; ++i) {
          nvc0->m2mf_copy_rect(nvc0, &tx->rect[0], &tx->rect[1],

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to