nv50/nvc0: make transfers aware of PIPE_TRANSFER_MAP_DIRECTLY
PATCH 1/1 nv50/nvc0: make transfers aware of PIPE_TRANSFER_MAP_DIRECTLY
If state tracker asked us to map resource directly and we can't do it (because of tiling), return NULL instead of doing full transfer
- state tracker should handle it and fallback to some other method or repeat transfer without PIPE_TRANSFER_MAP_DIRECTLY.
It greatly improves performance of xorg state tracker on nv50+, because fallback (DFS/UTS) is much faster than full transfer.
--- src/gallium/drivers/nv50/nv50_transfer.c | 31 +++++++++++++++++++--------- src/gallium/drivers/nvc0/nvc0_transfer.c | 32 ++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 20 deletions(-)
src/gallium/drivers/nv50/nv50_transfer.c +21 -10
@@ -209,6 +209,10 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,uint32_t w, h, d, z, layer;int ret; +if ((usage &PIPE_TRANSFER_MAP_DIRECTLY ) && +nouveau_bo_tile_layout (mt->base.bo)) +return NULL ; +if (mt->layout_3d) { z = box->z; d =u_minify (res->depth0, level);
@@ -252,6 +256,11 @@ nv50_miptree_transfer_new(struct pipe_context *pctx, tx->rect[0 ].pitch = lvl->pitch; tx->rect[0 ].domain =NOUVEAU_BO_VRAM ; +if (usage &PIPE_TRANSFER_MAP_DIRECTLY ) { + tx->rect[1 ] = tx->rect[0 ]; +return &tx->base; + } + size = tx->base.layer_stride; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
@@ -296,19 +305,21 @@ nv50_miptree_transfer_del(struct pipe_context *pctx,struct nv50_miptree *mt =nv50_miptree (tx->base.resource);unsigned i; -if (tx->base.usage &PIPE_TRANSFER_WRITE ) { -for (i =0 ; i < tx->base.box.depth; ++i) { -nv50_m2mf_transfer_rect (pscreen, &tx->rect[0 ], &tx->rect[1 ], - tx->nblocksx, tx->nblocksy); -if (mt->layout_3d) - tx->rect[0 ].z++; -else - tx->rect[0 ].base += mt->layer_stride; - tx->rect[1 ].base += tx->nblocksy * tx->base.stride; +if (!(tx->base.usage &PIPE_TRANSFER_MAP_DIRECTLY )) { +if (tx->base.usage &PIPE_TRANSFER_WRITE ) { +for (i =0 ; i < tx->base.box.depth; ++i) { +nv50_m2mf_transfer_rect (pscreen, &tx->rect[0 ], &tx->rect[1 ], + tx->nblocksx, tx->nblocksy); +if (mt->layout_3d) + tx->rect[0 ].z++; +else + tx->rect[0 ].base += mt->layer_stride; + tx->rect[1 ].base += tx->nblocksy * tx->base.stride; + } } +nouveau_bo_ref (NULL , &tx->rect[1 ].bo); } -nouveau_bo_ref (NULL , &tx->rect[1 ].bo);pipe_resource_reference (&transfer->resource,NULL );FREE (tx);
src/gallium/drivers/nvc0/nvc0_transfer.c +22 -10
@@ -246,6 +246,10 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,uint32_t w, h, d, z, layer;int ret; +if ((usage &PIPE_TRANSFER_MAP_DIRECTLY ) && +nouveau_bo_tile_layout (mt->base.bo)) +return NULL ; + tx =CALLOC_STRUCT (nvc0_transfer);if (!tx)return NULL ;
@@ -290,6 +294,11 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx, tx->rect[0 ].pitch = lvl->pitch; tx->rect[0 ].domain =NOUVEAU_BO_VRAM ; +if (usage &PIPE_TRANSFER_MAP_DIRECTLY ) { + tx->rect[1 ] = tx->rect[0 ]; +return &tx->base; + } + size = tx->base.layer_stride; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
@@ -334,19 +343,22 @@ nvc0_miptree_transfer_del(struct pipe_context *pctx,struct nvc0_miptree *mt =nvc0_miptree (tx->base.resource);unsigned i; -if (tx->base.usage &PIPE_TRANSFER_WRITE ) { -for (i =0 ; i < tx->nlayers; ++i) { -nvc0_m2mf_transfer_rect (pscreen, &tx->rect[0 ], &tx->rect[1 ], - tx->nblocksx, tx->nblocksy); -if (mt->layout_3d) - tx->rect[0 ].z++; -else - tx->rect[0 ].base += mt->layer_stride; - tx->rect[1 ].base += tx->nblocksy * tx->base.stride; +if (!(tx->base.usage &PIPE_TRANSFER_MAP_DIRECTLY )) { +if (tx->base.usage &PIPE_TRANSFER_WRITE ) { +for (i =0 ; i < tx->nlayers; ++i) { +nvc0_m2mf_transfer_rect (pscreen, &tx->rect[0 ], &tx->rect[1 ], + tx->nblocksx, tx->nblocksy); +if (mt->layout_3d) + tx->rect[0 ].z++; +else + tx->rect[0 ].base += mt->layer_stride; + tx->rect[1 ].base += tx->nblocksy * tx->base.stride; + } } + +nouveau_bo_ref (NULL , &tx->rect[1 ].bo); } -nouveau_bo_ref (NULL , &tx->rect[1 ].bo);pipe_resource_reference (&transfer->resource,NULL );FREE (tx);
Signature · 1 line
1.7.4.1
PATCH v2 1/1 nv50/nvc0: make transfers aware of PIPE_TRANSFER_MAP_DIRECTLY
If state tracker asked us to map resource directly and we can't do it (because of tiling), return NULL instead of doing full transfer
- state tracker should handle it and fallback to some other method or repeat transfer without PIPE_TRANSFER_MAP_DIRECTLY.
It greatly improves performance of xorg state tracker on nv50+, because its fallback (DFS/UTS) is much faster than full transfer.
--- src/gallium/drivers/nv50/nv50_transfer.c | 3 +++ src/gallium/drivers/nvc0/nvc0_transfer.c | 3 +++ 2 files changed, 6 insertions(+), 0 deletions(-)
src/gallium/drivers/nv50/nv50_transfer.c +3 -0
@@ -209,6 +209,9 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,uint32_t w, h, d, z, layer;int ret; +if (usage &PIPE_TRANSFER_MAP_DIRECTLY ) +return NULL ; +if (mt->layout_3d) { z = box->z; d =u_minify (res->depth0, level);
src/gallium/drivers/nvc0/nvc0_transfer.c +3 -0
@@ -246,6 +246,9 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,uint32_t w, h, d, z, layer;int ret; +if (usage &PIPE_TRANSFER_MAP_DIRECTLY ) +return NULL ; + tx =CALLOC_STRUCT (nvc0_transfer);if (!tx)return NULL ;
Signature · 1 line
1.7.4.1