1
#include "pipe/p_state.h"
2
#include "pipe/p_defines.h"
3
#include "util/u_inlines.h"
4
#include "util/u_format.h"
5
#include "util/u_memory.h"
6
#include "util/u_math.h"
7
#include "nouveau/nouveau_winsys.h"
8
#include "nv30_context.h"
9
#include "nv30_screen.h"
10
#include "nv30_state.h"
12
struct nv30_transfer {
13
struct pipe_transfer base;
14
struct pipe_surface *surface;
19
nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
20
struct pipe_texture *template)
22
memset(template, 0, sizeof(struct pipe_texture));
23
template->target = pt->target;
24
template->format = pt->format;
25
template->width0 = width;
26
template->height0 = height;
28
template->last_level = 0;
29
template->nr_samples = pt->nr_samples;
31
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
32
NOUVEAU_TEXTURE_USAGE_LINEAR;
35
static struct pipe_transfer *
36
nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
37
unsigned face, unsigned level, unsigned zslice,
38
enum pipe_transfer_usage usage,
39
unsigned x, unsigned y, unsigned w, unsigned h)
41
struct nv30_miptree *mt = (struct nv30_miptree *)pt;
42
struct nv30_transfer *tx;
43
struct pipe_texture tx_tex_template, *tx_tex;
45
tx = CALLOC_STRUCT(nv30_transfer);
49
pipe_texture_reference(&tx->base.texture, pt);
54
tx->base.stride = mt->level[level].pitch;
55
tx->base.usage = usage;
57
tx->base.level = level;
58
tx->base.zslice = zslice;
60
/* Direct access to texture */
61
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
62
debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
63
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
66
tx->surface = pscreen->get_tex_surface(pscreen, pt,
68
pipe_transfer_buffer_flags(&tx->base));
74
nv30_compatible_transfer_tex(pt, w, h, &tx_tex_template);
76
tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
83
tx->base.stride = ((struct nv30_miptree*)tx_tex)->level[0].pitch;
85
tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
87
pipe_transfer_buffer_flags(&tx->base));
89
pipe_texture_reference(&tx_tex, NULL);
93
pipe_surface_reference(&tx->surface, NULL);
98
if (usage & PIPE_TRANSFER_READ) {
99
struct nv30_screen *nvscreen = nv30_screen(pscreen);
100
struct pipe_surface *src;
102
src = pscreen->get_tex_surface(pscreen, pt,
104
PIPE_BUFFER_USAGE_GPU_READ);
106
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
107
/* TODO: Check if SIFM can un-swizzle */
108
nvscreen->eng2d->copy(nvscreen->eng2d,
113
pipe_surface_reference(&src, NULL);
120
nv30_transfer_del(struct pipe_transfer *ptx)
122
struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
124
if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
125
struct pipe_screen *pscreen = ptx->texture->screen;
126
struct nv30_screen *nvscreen = nv30_screen(pscreen);
127
struct pipe_surface *dst;
129
dst = pscreen->get_tex_surface(pscreen, ptx->texture,
130
ptx->face, ptx->level, ptx->zslice,
131
PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);
133
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
134
nvscreen->eng2d->copy(nvscreen->eng2d,
135
dst, tx->base.x, tx->base.y,
137
tx->base.width, tx->base.height);
139
pipe_surface_reference(&dst, NULL);
142
pipe_surface_reference(&tx->surface, NULL);
143
pipe_texture_reference(&ptx->texture, NULL);
148
nv30_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
150
struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
151
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
152
struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture;
153
void *map = pipe_buffer_map(pscreen, mt->buffer,
154
pipe_transfer_buffer_flags(ptx));
157
return map + ns->base.offset;
159
return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
163
nv30_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
165
struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
166
struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture;
168
pipe_buffer_unmap(pscreen, mt->buffer);
172
nv30_screen_init_transfer_functions(struct pipe_screen *pscreen)
174
pscreen->get_tex_transfer = nv30_transfer_new;
175
pscreen->tex_transfer_destroy = nv30_transfer_del;
176
pscreen->transfer_map = nv30_transfer_map;
177
pscreen->transfer_unmap = nv30_transfer_unmap;