1 #include <pipe/p_state.h>
2 #include <pipe/p_defines.h>
3 #include <pipe/p_inlines.h>
4 #include <util/u_memory.h>
5 #include <nouveau/nouveau_winsys.h>
6 #include "nv20_context.h"
7 #include "nv20_screen.h"
8 #include "nv20_state.h"
10 struct nv20_transfer
{
11 struct pipe_transfer base
;
12 struct pipe_surface
*surface
;
16 static unsigned nv20_usage_tx_to_buf(unsigned tx_usage
)
19 case PIPE_TRANSFER_READ
:
20 return PIPE_BUFFER_USAGE_CPU_READ
;
21 case PIPE_TRANSFER_WRITE
:
22 return PIPE_BUFFER_USAGE_CPU_WRITE
;
23 case PIPE_TRANSFER_READ_WRITE
:
24 return PIPE_BUFFER_USAGE_CPU_READ_WRITE
;
33 nv20_compatible_transfer_tex(struct pipe_texture
*pt
, unsigned level
,
34 struct pipe_texture
*template)
36 memset(template, 0, sizeof(struct pipe_texture
));
37 template->target
= pt
->target
;
38 template->format
= pt
->format
;
39 template->width
[0] = pt
->width
[level
];
40 template->height
[0] = pt
->height
[level
];
41 template->depth
[0] = 1;
42 template->block
= pt
->block
;
43 template->nblocksx
[0] = pt
->nblocksx
[level
];
44 template->nblocksy
[0] = pt
->nblocksx
[level
];
45 template->last_level
= 0;
46 template->compressed
= pt
->compressed
;
47 template->nr_samples
= pt
->nr_samples
;
49 template->tex_usage
= PIPE_TEXTURE_USAGE_DYNAMIC
|
50 NOUVEAU_TEXTURE_USAGE_LINEAR
;
53 static struct pipe_transfer
*
54 nv20_transfer_new(struct pipe_screen
*pscreen
, struct pipe_texture
*pt
,
55 unsigned face
, unsigned level
, unsigned zslice
,
56 enum pipe_transfer_usage usage
,
57 unsigned x
, unsigned y
, unsigned w
, unsigned h
)
59 struct nv20_miptree
*mt
= (struct nv20_miptree
*)pt
;
60 struct nv20_transfer
*tx
;
61 struct pipe_texture tx_tex_template
, *tx_tex
;
63 tx
= CALLOC_STRUCT(nv20_transfer
);
67 tx
->base
.refcount
= 1;
68 pipe_texture_reference(&tx
->base
.texture
, pt
);
69 tx
->base
.format
= pt
->format
;
74 tx
->base
.block
= pt
->block
;
75 tx
->base
.nblocksx
= pt
->nblocksx
[level
];
76 tx
->base
.nblocksy
= pt
->nblocksy
[level
];
77 tx
->base
.stride
= mt
->level
[level
].pitch
;
78 tx
->base
.usage
= usage
;
80 tx
->base
.level
= level
;
81 tx
->base
.zslice
= zslice
;
83 /* Direct access to texture */
84 if ((pt
->tex_usage
& PIPE_TEXTURE_USAGE_DYNAMIC
||
85 debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE
/*XXX:FALSE*/)) &&
86 pt
->tex_usage
& NOUVEAU_TEXTURE_USAGE_LINEAR
)
89 tx
->surface
= pscreen
->get_tex_surface(pscreen
, pt
,
91 nv20_usage_tx_to_buf(usage
));
97 nv20_compatible_transfer_tex(pt
, level
, &tx_tex_template
);
99 tx_tex
= pscreen
->texture_create(pscreen
, &tx_tex_template
);
106 tx
->surface
= pscreen
->get_tex_surface(pscreen
, tx_tex
,
108 nv20_usage_tx_to_buf(usage
));
110 pipe_texture_reference(&tx_tex
, NULL
);
114 pipe_surface_reference(&tx
->surface
, NULL
);
119 if (usage
!= PIPE_TRANSFER_WRITE
) {
120 struct nv20_screen
*nvscreen
= nv20_screen(pscreen
);
121 struct pipe_surface
*src
;
123 src
= pscreen
->get_tex_surface(pscreen
, pt
,
125 PIPE_BUFFER_USAGE_GPU_READ
);
127 /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
128 /* TODO: Check if SIFM can un-swizzle */
129 nvscreen
->eng2d
->copy(nvscreen
->eng2d
,
132 src
->width
, src
->height
);
134 pipe_surface_reference(&src
, NULL
);
141 nv20_transfer_del(struct pipe_screen
*pscreen
, struct pipe_transfer
**pptx
)
143 struct pipe_transfer
*ptx
= *pptx
;
144 struct nv20_transfer
*tx
= (struct nv20_transfer
*)ptx
;
146 if (!tx
->direct
&& ptx
->usage
!= PIPE_TRANSFER_READ
) {
147 struct nv20_screen
*nvscreen
= nv20_screen(pscreen
);
148 struct pipe_surface
*dst
;
150 dst
= pscreen
->get_tex_surface(pscreen
, ptx
->texture
,
151 ptx
->face
, ptx
->level
, ptx
->zslice
,
152 PIPE_BUFFER_USAGE_GPU_WRITE
);
154 /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
155 nvscreen
->eng2d
->copy(nvscreen
->eng2d
,
158 dst
->width
, dst
->height
);
160 pipe_surface_reference(&dst
, NULL
);
167 pipe_surface_reference(&tx
->surface
, NULL
);
168 pipe_texture_reference(&ptx
->texture
, NULL
);
173 nv20_transfer_map(struct pipe_screen
*pscreen
, struct pipe_transfer
*ptx
)
175 struct nv20_transfer
*tx
= (struct nv20_transfer
*)ptx
;
176 struct nv04_surface
*ns
= (struct nv04_surface
*)tx
->surface
;
177 struct nv20_miptree
*mt
= (struct nv20_miptree
*)tx
->surface
->texture
;
178 void *map
= pipe_buffer_map(pscreen
, mt
->buffer
,
179 nv20_usage_tx_to_buf(ptx
->usage
));
181 return map
+ ns
->base
.offset
+
182 ptx
->y
* ns
->pitch
+ ptx
->x
* ptx
->block
.size
;
186 nv20_transfer_unmap(struct pipe_screen
*pscreen
, struct pipe_transfer
*ptx
)
188 struct nv20_transfer
*tx
= (struct nv20_transfer
*)ptx
;
189 struct nv20_miptree
*mt
= (struct nv20_miptree
*)tx
->surface
->texture
;
191 pipe_buffer_unmap(pscreen
, mt
->buffer
);
195 nv20_screen_init_transfer_functions(struct pipe_screen
*pscreen
)
197 pscreen
->get_tex_transfer
= nv20_transfer_new
;
198 pscreen
->tex_transfer_release
= nv20_transfer_del
;
199 pscreen
->transfer_map
= nv20_transfer_map
;
200 pscreen
->transfer_unmap
= nv20_transfer_unmap
;