summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvfx/nvfx_transfer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nvfx/nvfx_transfer.c')
-rw-r--r--src/gallium/drivers/nvfx/nvfx_transfer.c137
1 files changed, 79 insertions, 58 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c
index 1c250e9fe44..59ab14826c3 100644
--- a/src/gallium/drivers/nvfx/nvfx_transfer.c
+++ b/src/gallium/drivers/nvfx/nvfx_transfer.c
@@ -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);
}