From: Luca Barbieri Date: Sat, 20 Feb 2010 19:07:10 +0000 (+0100) Subject: nv30, nv40: unify identical nv[34]0_transfer.c X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d084d189d03dc89a3161a131f1b386840c06ad61;p=mesa.git nv30, nv40: unify identical nv[34]0_transfer.c --- diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index 27f19da75cc..f18295cefc2 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -21,7 +21,6 @@ C_SOURCES = \ nv30_state_viewport.c \ nv30_state_zsa.c \ nv30_surface.c \ - nv30_transfer.c \ nv30_vbo.c \ nv30_vertprog.c diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 74be578705c..ee2c465bc6d 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -76,7 +76,7 @@ nv30_create(struct pipe_screen *pscreen, void *priv) nv30_init_query_functions(nvfx); nv30_init_surface_functions(nvfx); nv30_init_state_functions(nvfx); - nv30_init_transfer_functions(nvfx); + nvfx_init_transfer_functions(nvfx); /* Create, configure, and install fallback swtnl path */ nvfx->draw = draw_create(); diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 8032bcd9797..9f28d49706f 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -6,7 +6,6 @@ extern void nv30_init_state_functions(struct nvfx_context *nvfx); extern void nv30_init_surface_functions(struct nvfx_context *nvfx); extern void nv30_init_query_functions(struct nvfx_context *nvfx); -extern void nv30_init_transfer_functions(struct nvfx_context *nvfx); extern void nv30_screen_init_miptree_functions(struct pipe_screen *pscreen); diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c deleted file mode 100644 index 3d71df52b90..00000000000 --- a/src/gallium/drivers/nv30/nv30_transfer.c +++ /dev/null @@ -1,182 +0,0 @@ -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_memory.h" -#include "util/u_math.h" -#include "nouveau/nouveau_winsys.h" -#include "nv30_context.h" -#include "nvfx_screen.h" -#include "nvfx_state.h" - -struct nv30_transfer { - struct pipe_transfer base; - struct pipe_surface *surface; - boolean direct; -}; - -static void -nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, - struct pipe_texture *template) -{ - memset(template, 0, sizeof(struct pipe_texture)); - template->target = pt->target; - template->format = pt->format; - template->width0 = width; - template->height0 = height; - template->depth0 = 1; - template->last_level = 0; - template->nr_samples = pt->nr_samples; - - template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | - NOUVEAU_TEXTURE_USAGE_LINEAR; -} - -static struct pipe_transfer * -nv30_transfer_new(struct pipe_context *pcontext, 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_screen *pscreen = pcontext->screen; - struct nvfx_miptree *mt = (struct nvfx_miptree *)pt; - struct nv30_transfer *tx; - struct pipe_texture tx_tex_template, *tx_tex; - - tx = CALLOC_STRUCT(nv30_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; - tx->base.usage = usage; - tx->base.face = face; - tx->base.level = level; - tx->base.zslice = zslice; - - /* Direct access to texture */ - if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || - debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) && - pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) - { - tx->direct = true; - tx->surface = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - pipe_transfer_buffer_flags(&tx->base)); - return &tx->base; - } - - tx->direct = false; - - nv30_compatible_transfer_tex(pt, w, h, &tx_tex_template); - - tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); - if (!tx_tex) - { - FREE(tx); - return NULL; - } - - tx->base.stride = ((struct nvfx_miptree*)tx_tex)->level[0].pitch; - - tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, - 0, 0, 0, - pipe_transfer_buffer_flags(&tx->base)); - - pipe_texture_reference(&tx_tex, NULL); - - if (!tx->surface) - { - pipe_surface_reference(&tx->surface, NULL); - FREE(tx); - return NULL; - } - - if (usage & PIPE_TRANSFER_READ) { - struct nvfx_screen *nvscreen = nvfx_screen(pscreen); - struct pipe_surface *src; - - src = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); - - /* 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); - - pipe_surface_reference(&src, NULL); - } - - return &tx->base; -} - -static void -nv30_transfer_del(struct pipe_context *pcontext, - struct pipe_transfer *ptx) -{ - struct nv30_transfer *tx = (struct nv30_transfer *)ptx; - - if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { - struct pipe_screen *pscreen = pcontext->screen; - 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); - - /* 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, - tx->surface, 0, 0, - tx->base.width, tx->base.height); - - pipe_surface_reference(&dst, NULL); - } - - pipe_surface_reference(&tx->surface, NULL); - pipe_texture_reference(&ptx->texture, NULL); - FREE(ptx); -} - -static void * -nv30_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx) -{ - struct pipe_screen *pscreen = pcontext->screen; - struct nv30_transfer *tx = (struct nv30_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)); - - 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); -} - -static void -nv30_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx) -{ - struct pipe_screen *pscreen = pcontext->screen; - struct nv30_transfer *tx = (struct nv30_transfer *)ptx; - struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture; - - pipe_buffer_unmap(pscreen, mt->buffer); -} - -void -nv30_init_transfer_functions(struct nvfx_context *nvfx) -{ - nvfx->pipe.get_tex_transfer = nv30_transfer_new; - nvfx->pipe.tex_transfer_destroy = nv30_transfer_del; - nvfx->pipe.transfer_map = nv30_transfer_map; - nvfx->pipe.transfer_unmap = nv30_transfer_unmap; -} diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 031c943de52..8d09ef807f8 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -21,7 +21,6 @@ C_SOURCES = \ nv40_state_viewport.c \ nv40_state_zsa.c \ nv40_surface.c \ - nv40_transfer.c \ nv40_vbo.c \ nv40_vertprog.c diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index cb249dd5d76..9934b582eef 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -76,7 +76,7 @@ nv40_create(struct pipe_screen *pscreen, void *priv) nv40_init_query_functions(nvfx); nv40_init_surface_functions(nvfx); nv40_init_state_functions(nvfx); - nv40_init_transfer_functions(nvfx); + nvfx_init_transfer_functions(nvfx); /* Create, configure, and install fallback swtnl path */ nvfx->draw = draw_create(); diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index f9c0a9eb29e..e7c6d5ad86d 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -6,7 +6,6 @@ extern void nv40_init_state_functions(struct nvfx_context *nvfx); extern void nv40_init_surface_functions(struct nvfx_context *nvfx); extern void nv40_init_query_functions(struct nvfx_context *nvfx); -extern void nv40_init_transfer_functions(struct nvfx_context *nvfx); extern void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen); diff --git a/src/gallium/drivers/nvfx/Makefile b/src/gallium/drivers/nvfx/Makefile index 6959efa390f..699cbedbc84 100644 --- a/src/gallium/drivers/nvfx/Makefile +++ b/src/gallium/drivers/nvfx/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current LIBNAME = nvfx C_SOURCES = \ - nvfx_clear.c + nvfx_clear.c \ + nvfx_transfer.c include ../../Makefile.template diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index 0aaa4964e2b..38d1142ff97 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -185,4 +185,7 @@ struct nvfx_state_entry { extern void nvfx_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, double depth, unsigned stencil); +/* nvfx_transfer.c */ +extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx); + #endif diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c new file mode 100644 index 00000000000..409b354d582 --- /dev/null +++ b/src/gallium/drivers/nvfx/nvfx_transfer.c @@ -0,0 +1,182 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_memory.h" +#include "util/u_math.h" +#include "nouveau/nouveau_winsys.h" +#include "nvfx_context.h" +#include "nvfx_screen.h" +#include "nvfx_state.h" + +struct nvfx_transfer { + struct pipe_transfer base; + struct pipe_surface *surface; + boolean direct; +}; + +static void +nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, + struct pipe_texture *template) +{ + memset(template, 0, sizeof(struct pipe_texture)); + template->target = pt->target; + template->format = pt->format; + template->width0 = width; + template->height0 = height; + template->depth0 = 1; + template->last_level = 0; + template->nr_samples = pt->nr_samples; + + template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | + NOUVEAU_TEXTURE_USAGE_LINEAR; +} + +static struct pipe_transfer * +nvfx_transfer_new(struct pipe_context *pcontext, 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_screen *pscreen = pcontext->screen; + struct nvfx_miptree *mt = (struct nvfx_miptree *)pt; + struct nvfx_transfer *tx; + struct pipe_texture tx_tex_template, *tx_tex; + + 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; + tx->base.usage = usage; + tx->base.face = face; + tx->base.level = level; + tx->base.zslice = zslice; + + /* Direct access to texture */ + if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || + debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) && + pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) + { + tx->direct = true; + tx->surface = pscreen->get_tex_surface(pscreen, pt, + face, level, zslice, + pipe_transfer_buffer_flags(&tx->base)); + return &tx->base; + } + + tx->direct = false; + + nvfx_compatible_transfer_tex(pt, w, h, &tx_tex_template); + + tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); + if (!tx_tex) + { + FREE(tx); + return NULL; + } + + tx->base.stride = ((struct nvfx_miptree*)tx_tex)->level[0].pitch; + + tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, + 0, 0, 0, + pipe_transfer_buffer_flags(&tx->base)); + + pipe_texture_reference(&tx_tex, NULL); + + if (!tx->surface) + { + pipe_surface_reference(&tx->surface, NULL); + FREE(tx); + return NULL; + } + + if (usage & PIPE_TRANSFER_READ) { + struct nvfx_screen *nvscreen = nvfx_screen(pscreen); + struct pipe_surface *src; + + src = pscreen->get_tex_surface(pscreen, pt, + face, level, zslice, + PIPE_BUFFER_USAGE_GPU_READ); + + /* 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); + + pipe_surface_reference(&src, NULL); + } + + return &tx->base; +} + +static void +nvfx_transfer_del(struct pipe_context *pcontext, + struct pipe_transfer *ptx) +{ + struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx; + + if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { + struct pipe_screen *pscreen = pcontext->screen; + 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); + + /* 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, + tx->surface, 0, 0, + tx->base.width, tx->base.height); + + pipe_surface_reference(&dst, NULL); + } + + pipe_surface_reference(&tx->surface, NULL); + pipe_texture_reference(&ptx->texture, NULL); + FREE(ptx); +} + +static void * +nvfx_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx) +{ + struct pipe_screen *pscreen = pcontext->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)); + + 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); +} + +static void +nvfx_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx) +{ + struct pipe_screen *pscreen = pcontext->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; +}