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 <util/u_math.h>
6 #include <nouveau/nouveau_winsys.h>
7 #include "nv40_context.h"
8 #include "nv40_screen.h"
9 #include "nv40_state.h"
11 struct nv40_transfer
{
12 struct pipe_transfer base
;
13 struct pipe_surface
*surface
;
18 nv40_compatible_transfer_tex(struct pipe_texture
*pt
, unsigned level
,
19 struct pipe_texture
*template)
21 memset(template, 0, sizeof(struct pipe_texture
));
22 template->target
= pt
->target
;
23 template->format
= pt
->format
;
24 template->width0
= u_minify(pt
->width0
, level
);
25 template->height0
= u_minify(pt
->height0
, level
);
27 template->last_level
= 0;
28 template->nr_samples
= pt
->nr_samples
;
30 template->tex_usage
= PIPE_TEXTURE_USAGE_DYNAMIC
|
31 NOUVEAU_TEXTURE_USAGE_LINEAR
;
34 static struct pipe_transfer
*
35 nv40_transfer_new(struct pipe_screen
*pscreen
, struct pipe_texture
*pt
,
36 unsigned face
, unsigned level
, unsigned zslice
,
37 enum pipe_transfer_usage usage
,
38 unsigned x
, unsigned y
, unsigned w
, unsigned h
)
40 struct nv40_miptree
*mt
= (struct nv40_miptree
*)pt
;
41 struct nv40_transfer
*tx
;
42 struct pipe_texture tx_tex_template
, *tx_tex
;
44 tx
= CALLOC_STRUCT(nv40_transfer
);
48 pipe_texture_reference(&tx
->base
.texture
, pt
);
53 tx
->base
.stride
= mt
->level
[level
].pitch
;
54 tx
->base
.usage
= usage
;
56 tx
->base
.level
= level
;
57 tx
->base
.zslice
= zslice
;
59 /* Direct access to texture */
60 if ((pt
->tex_usage
& PIPE_TEXTURE_USAGE_DYNAMIC
||
61 debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE
/*XXX:FALSE*/)) &&
62 pt
->tex_usage
& NOUVEAU_TEXTURE_USAGE_LINEAR
)
65 tx
->surface
= pscreen
->get_tex_surface(pscreen
, pt
,
67 pipe_transfer_buffer_flags(&tx
->base
));
73 nv40_compatible_transfer_tex(pt
, level
, &tx_tex_template
);
75 tx_tex
= pscreen
->texture_create(pscreen
, &tx_tex_template
);
82 tx
->surface
= pscreen
->get_tex_surface(pscreen
, tx_tex
,
84 pipe_transfer_buffer_flags(&tx
->base
));
86 pipe_texture_reference(&tx_tex
, NULL
);
90 pipe_surface_reference(&tx
->surface
, NULL
);
95 if (usage
& PIPE_TRANSFER_READ
) {
96 struct nv40_screen
*nvscreen
= nv40_screen(pscreen
);
97 struct pipe_surface
*src
;
99 src
= pscreen
->get_tex_surface(pscreen
, pt
,
101 PIPE_BUFFER_USAGE_GPU_READ
);
103 /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
104 /* TODO: Check if SIFM can un-swizzle */
105 nvscreen
->eng2d
->copy(nvscreen
->eng2d
,
108 src
->width
, src
->height
);
110 pipe_surface_reference(&src
, NULL
);
117 nv40_transfer_del(struct pipe_transfer
*ptx
)
119 struct nv40_transfer
*tx
= (struct nv40_transfer
*)ptx
;
121 if (!tx
->direct
&& (ptx
->usage
& PIPE_TRANSFER_WRITE
)) {
122 struct pipe_screen
*pscreen
= ptx
->texture
->screen
;
123 struct nv40_screen
*nvscreen
= nv40_screen(pscreen
);
124 struct pipe_surface
*dst
;
126 dst
= pscreen
->get_tex_surface(pscreen
, ptx
->texture
,
127 ptx
->face
, ptx
->level
, ptx
->zslice
,
128 PIPE_BUFFER_USAGE_GPU_WRITE
);
130 /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
131 nvscreen
->eng2d
->copy(nvscreen
->eng2d
,
134 dst
->width
, dst
->height
);
136 pipe_surface_reference(&dst
, NULL
);
139 pipe_surface_reference(&tx
->surface
, NULL
);
140 pipe_texture_reference(&ptx
->texture
, NULL
);
145 nv40_transfer_map(struct pipe_screen
*pscreen
, struct pipe_transfer
*ptx
)
147 struct nv40_transfer
*tx
= (struct nv40_transfer
*)ptx
;
148 struct nv04_surface
*ns
= (struct nv04_surface
*)tx
->surface
;
149 struct nv40_miptree
*mt
= (struct nv40_miptree
*)tx
->surface
->texture
;
150 void *map
= pipe_buffer_map(pscreen
, mt
->buffer
,
151 pipe_transfer_buffer_flags(ptx
));
153 return map
+ ns
->base
.offset
+
154 ptx
->y
* ns
->pitch
+ ptx
->x
* pf_get_blocksize(ptx
->texture
->format
);
158 nv40_transfer_unmap(struct pipe_screen
*pscreen
, struct pipe_transfer
*ptx
)
160 struct nv40_transfer
*tx
= (struct nv40_transfer
*)ptx
;
161 struct nv40_miptree
*mt
= (struct nv40_miptree
*)tx
->surface
->texture
;
163 pipe_buffer_unmap(pscreen
, mt
->buffer
);
167 nv40_screen_init_transfer_functions(struct pipe_screen
*pscreen
)
169 pscreen
->get_tex_transfer
= nv40_transfer_new
;
170 pscreen
->tex_transfer_destroy
= nv40_transfer_del
;
171 pscreen
->transfer_map
= nv40_transfer_map
;
172 pscreen
->transfer_unmap
= nv40_transfer_unmap
;