1 #include "pipe/p_context.h"
2 #include "pipe/p_format.h"
3 #include "util/u_format.h"
4 #include "util/u_math.h"
5 #include "util/u_memory.h"
7 #include "nouveau/nouveau_winsys.h"
8 #include "nouveau/nouveau_util.h"
9 #include "nouveau/nouveau_screen.h"
10 #include "nv04_surface_2d.h"
13 nv04_surface_format(enum pipe_format format
)
16 case PIPE_FORMAT_A8_UNORM
:
17 case PIPE_FORMAT_L8_UNORM
:
18 case PIPE_FORMAT_I8_UNORM
:
19 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8
;
20 case PIPE_FORMAT_R16_SNORM
:
21 case PIPE_FORMAT_R5G6B5_UNORM
:
22 case PIPE_FORMAT_Z16_UNORM
:
23 case PIPE_FORMAT_A8L8_UNORM
:
24 return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5
;
25 case PIPE_FORMAT_X8R8G8B8_UNORM
:
26 case PIPE_FORMAT_A8R8G8B8_UNORM
:
27 return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8
;
28 case PIPE_FORMAT_Z24S8_UNORM
:
29 case PIPE_FORMAT_Z24X8_UNORM
:
30 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32
;
37 nv04_rect_format(enum pipe_format format
)
40 case PIPE_FORMAT_A8_UNORM
:
41 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8
;
42 case PIPE_FORMAT_R5G6B5_UNORM
:
43 case PIPE_FORMAT_A8L8_UNORM
:
44 case PIPE_FORMAT_Z16_UNORM
:
45 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5
;
46 case PIPE_FORMAT_X8R8G8B8_UNORM
:
47 case PIPE_FORMAT_A8R8G8B8_UNORM
:
48 case PIPE_FORMAT_Z24S8_UNORM
:
49 case PIPE_FORMAT_Z24X8_UNORM
:
50 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8
;
57 nv04_scaled_image_format(enum pipe_format format
)
60 case PIPE_FORMAT_A8_UNORM
:
61 case PIPE_FORMAT_L8_UNORM
:
62 case PIPE_FORMAT_I8_UNORM
:
63 return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_Y8
;
64 case PIPE_FORMAT_A1R5G5B5_UNORM
:
65 return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5
;
66 case PIPE_FORMAT_A8R8G8B8_UNORM
:
67 return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8
;
68 case PIPE_FORMAT_X8R8G8B8_UNORM
:
69 return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8
;
70 case PIPE_FORMAT_R5G6B5_UNORM
:
71 case PIPE_FORMAT_R16_SNORM
:
72 case PIPE_FORMAT_A8L8_UNORM
:
73 return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5
;
79 static INLINE
unsigned
80 nv04_swizzle_bits_square(unsigned x
, unsigned y
)
82 unsigned u
= (x
& 0x001) << 0 |
95 unsigned v
= (y
& 0x001) << 1 |
110 /* rectangular swizzled textures are linear concatenations of swizzled square tiles */
111 static INLINE
unsigned
112 nv04_swizzle_bits(unsigned x
, unsigned y
, unsigned w
, unsigned h
)
114 unsigned s
= MIN2(w
, h
);
116 return (((x
| y
) & ~m
) * s
) | nv04_swizzle_bits_square(x
& m
, y
& m
);
120 nv04_surface_copy_swizzle(struct nv04_surface_2d
*ctx
,
121 struct pipe_surface
*dst
, int dx
, int dy
,
122 struct pipe_surface
*src
, int sx
, int sy
,
125 struct nouveau_channel
*chan
= ctx
->swzsurf
->channel
;
126 struct nouveau_grobj
*swzsurf
= ctx
->swzsurf
;
127 struct nouveau_grobj
*sifm
= ctx
->sifm
;
128 struct nouveau_bo
*src_bo
= nouveau_bo(ctx
->buf(src
));
129 struct nouveau_bo
*dst_bo
= nouveau_bo(ctx
->buf(dst
));
130 const unsigned src_pitch
= ((struct nv04_surface
*)src
)->pitch
;
131 /* Max width & height may not be the same on all HW, but must be POT */
132 const unsigned max_w
= 1024;
133 const unsigned max_h
= 1024;
134 unsigned sub_w
= w
> max_w
? max_w
: w
;
135 unsigned sub_h
= h
> max_h
? max_h
: h
;
139 /* Swizzled surfaces must be POT */
140 assert(util_is_pot(dst
->width
) && util_is_pot(dst
->height
));
142 /* If area is too large to copy in one shot we must copy it in POT chunks to meet alignment requirements */
143 assert(sub_w
== w
|| util_is_pot(sub_w
));
144 assert(sub_h
== h
|| util_is_pot(sub_h
));
146 MARK_RING (chan
, 8 + ((w
+sub_w
)/sub_w
)*((h
+sub_h
)/sub_h
)*17, 2 +
147 ((w
+sub_w
)/sub_w
)*((h
+sub_h
)/sub_h
)*2);
149 BEGIN_RING(chan
, swzsurf
, NV04_SWIZZLED_SURFACE_DMA_IMAGE
, 1);
150 OUT_RELOCo(chan
, dst_bo
,
151 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
153 BEGIN_RING(chan
, swzsurf
, NV04_SWIZZLED_SURFACE_FORMAT
, 1);
154 OUT_RING (chan
, nv04_surface_format(dst
->format
) |
155 log2i(dst
->width
) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT
|
156 log2i(dst
->height
) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT
);
158 BEGIN_RING(chan
, sifm
, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE
, 1);
159 OUT_RELOCo(chan
, src_bo
,
160 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
161 BEGIN_RING(chan
, sifm
, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE
, 1);
162 OUT_RING (chan
, swzsurf
->handle
);
164 for (y
= 0; y
< h
; y
+= sub_h
) {
165 sub_h
= MIN2(sub_h
, h
- y
);
167 for (x
= 0; x
< w
; x
+= sub_w
) {
168 sub_w
= MIN2(sub_w
, w
- x
);
170 /* Must be 64-byte aligned */
171 assert(!((dst
->offset
+ nv04_swizzle_bits(dx
+x
, dy
+y
, w
, h
) * util_format_get_blocksize(dst
->texture
->format
)) & 63));
173 BEGIN_RING(chan
, swzsurf
, NV04_SWIZZLED_SURFACE_OFFSET
, 1);
174 OUT_RELOCl(chan
, dst_bo
, dst
->offset
+ nv04_swizzle_bits(dx
+x
, dy
+y
, w
, h
) * util_format_get_blocksize(dst
->texture
->format
),
175 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
177 BEGIN_RING(chan
, sifm
, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION
, 9);
178 OUT_RING (chan
, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE
);
179 OUT_RING (chan
, nv04_scaled_image_format(src
->format
));
180 OUT_RING (chan
, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY
);
182 OUT_RING (chan
, sub_h
<< NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_H_SHIFT
| sub_w
);
184 OUT_RING (chan
, sub_h
<< NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE_H_SHIFT
| sub_w
);
185 OUT_RING (chan
, 1 << 20);
186 OUT_RING (chan
, 1 << 20);
188 BEGIN_RING(chan
, sifm
, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE
, 4);
189 OUT_RING (chan
, sub_h
<< NV04_SCALED_IMAGE_FROM_MEMORY_SIZE_H_SHIFT
| sub_w
);
190 OUT_RING (chan
, src_pitch
|
191 NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER
|
192 NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE
);
193 OUT_RELOCl(chan
, src_bo
, src
->offset
+ (sy
+y
) * src_pitch
+ (sx
+x
) * util_format_get_blocksize(src
->texture
->format
),
194 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
203 nv04_surface_copy_m2mf(struct nv04_surface_2d
*ctx
,
204 struct pipe_surface
*dst
, int dx
, int dy
,
205 struct pipe_surface
*src
, int sx
, int sy
, int w
, int h
)
207 struct nouveau_channel
*chan
= ctx
->m2mf
->channel
;
208 struct nouveau_grobj
*m2mf
= ctx
->m2mf
;
209 struct nouveau_bo
*src_bo
= nouveau_bo(ctx
->buf(src
));
210 struct nouveau_bo
*dst_bo
= nouveau_bo(ctx
->buf(dst
));
211 unsigned src_pitch
= ((struct nv04_surface
*)src
)->pitch
;
212 unsigned dst_pitch
= ((struct nv04_surface
*)dst
)->pitch
;
213 unsigned dst_offset
= dst
->offset
+ dy
* dst_pitch
+
214 dx
* util_format_get_blocksize(dst
->texture
->format
);
215 unsigned src_offset
= src
->offset
+ sy
* src_pitch
+
216 sx
* util_format_get_blocksize(src
->texture
->format
);
218 MARK_RING (chan
, 3 + ((h
/ 2047) + 1) * 9, 2 + ((h
/ 2047) + 1) * 2);
219 BEGIN_RING(chan
, m2mf
, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN
, 2);
220 OUT_RELOCo(chan
, src_bo
,
221 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
222 OUT_RELOCo(chan
, dst_bo
,
223 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
226 int count
= (h
> 2047) ? 2047 : h
;
228 BEGIN_RING(chan
, m2mf
, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN
, 8);
229 OUT_RELOCl(chan
, src_bo
, src_offset
,
230 NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
231 OUT_RELOCl(chan
, dst_bo
, dst_offset
,
232 NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_WR
);
233 OUT_RING (chan
, src_pitch
);
234 OUT_RING (chan
, dst_pitch
);
235 OUT_RING (chan
, w
* util_format_get_blocksize(src
->texture
->format
));
236 OUT_RING (chan
, count
);
237 OUT_RING (chan
, 0x0101);
241 src_offset
+= src_pitch
* count
;
242 dst_offset
+= dst_pitch
* count
;
249 nv04_surface_copy_blit(struct nv04_surface_2d
*ctx
, struct pipe_surface
*dst
,
250 int dx
, int dy
, struct pipe_surface
*src
, int sx
, int sy
,
253 struct nouveau_channel
*chan
= ctx
->surf2d
->channel
;
254 struct nouveau_grobj
*surf2d
= ctx
->surf2d
;
255 struct nouveau_grobj
*blit
= ctx
->blit
;
256 struct nouveau_bo
*src_bo
= nouveau_bo(ctx
->buf(src
));
257 struct nouveau_bo
*dst_bo
= nouveau_bo(ctx
->buf(dst
));
258 unsigned src_pitch
= ((struct nv04_surface
*)src
)->pitch
;
259 unsigned dst_pitch
= ((struct nv04_surface
*)dst
)->pitch
;
262 format
= nv04_surface_format(dst
->format
);
266 MARK_RING (chan
, 12, 4);
267 BEGIN_RING(chan
, surf2d
, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE
, 2);
268 OUT_RELOCo(chan
, src_bo
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
269 OUT_RELOCo(chan
, dst_bo
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
270 BEGIN_RING(chan
, surf2d
, NV04_CONTEXT_SURFACES_2D_FORMAT
, 4);
271 OUT_RING (chan
, format
);
272 OUT_RING (chan
, (dst_pitch
<< 16) | src_pitch
);
273 OUT_RELOCl(chan
, src_bo
, src
->offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
274 OUT_RELOCl(chan
, dst_bo
, dst
->offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
276 BEGIN_RING(chan
, blit
, 0x0300, 3);
277 OUT_RING (chan
, (sy
<< 16) | sx
);
278 OUT_RING (chan
, (dy
<< 16) | dx
);
279 OUT_RING (chan
, ( h
<< 16) | w
);
285 nv04_surface_copy(struct nv04_surface_2d
*ctx
, struct pipe_surface
*dst
,
286 int dx
, int dy
, struct pipe_surface
*src
, int sx
, int sy
,
289 unsigned src_pitch
= ((struct nv04_surface
*)src
)->pitch
;
290 unsigned dst_pitch
= ((struct nv04_surface
*)dst
)->pitch
;
291 int src_linear
= src
->texture
->tex_usage
& NOUVEAU_TEXTURE_USAGE_LINEAR
;
292 int dst_linear
= dst
->texture
->tex_usage
& NOUVEAU_TEXTURE_USAGE_LINEAR
;
294 assert(src
->format
== dst
->format
);
296 /* Setup transfer to swizzle the texture to vram if needed */
297 if (src_linear
&& !dst_linear
&& w
> 1 && h
> 1) {
298 nv04_surface_copy_swizzle(ctx
, dst
, dx
, dy
, src
, sx
, sy
, w
, h
);
302 /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback
303 * to NV_MEMORY_TO_MEMORY_FORMAT in this case.
305 if ((src
->offset
& 63) || (dst
->offset
& 63) ||
306 (src_pitch
& 63) || (dst_pitch
& 63)) {
307 nv04_surface_copy_m2mf(ctx
, dst
, dx
, dy
, src
, sx
, sy
, w
, h
);
311 nv04_surface_copy_blit(ctx
, dst
, dx
, dy
, src
, sx
, sy
, w
, h
);
315 nv04_surface_fill(struct nv04_surface_2d
*ctx
, struct pipe_surface
*dst
,
316 int dx
, int dy
, int w
, int h
, unsigned value
)
318 struct nouveau_channel
*chan
= ctx
->surf2d
->channel
;
319 struct nouveau_grobj
*surf2d
= ctx
->surf2d
;
320 struct nouveau_grobj
*rect
= ctx
->rect
;
321 struct nouveau_bo
*dst_bo
= nouveau_bo(ctx
->buf(dst
));
322 unsigned dst_pitch
= ((struct nv04_surface
*)dst
)->pitch
;
323 int cs2d_format
, gdirect_format
;
325 cs2d_format
= nv04_surface_format(dst
->format
);
326 assert(cs2d_format
>= 0);
328 gdirect_format
= nv04_rect_format(dst
->format
);
329 assert(gdirect_format
>= 0);
331 MARK_RING (chan
, 16, 4);
332 BEGIN_RING(chan
, surf2d
, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE
, 2);
333 OUT_RELOCo(chan
, dst_bo
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
334 OUT_RELOCo(chan
, dst_bo
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
335 BEGIN_RING(chan
, surf2d
, NV04_CONTEXT_SURFACES_2D_FORMAT
, 4);
336 OUT_RING (chan
, cs2d_format
);
337 OUT_RING (chan
, (dst_pitch
<< 16) | dst_pitch
);
338 OUT_RELOCl(chan
, dst_bo
, dst
->offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
339 OUT_RELOCl(chan
, dst_bo
, dst
->offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
341 BEGIN_RING(chan
, rect
, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT
, 1);
342 OUT_RING (chan
, gdirect_format
);
343 BEGIN_RING(chan
, rect
, NV04_GDI_RECTANGLE_TEXT_COLOR1_A
, 1);
344 OUT_RING (chan
, value
);
345 BEGIN_RING(chan
, rect
,
346 NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2);
347 OUT_RING (chan
, (dx
<< 16) | dy
);
348 OUT_RING (chan
, ( w
<< 16) | h
);
352 nv04_surface_2d_takedown(struct nv04_surface_2d
**pctx
)
354 struct nv04_surface_2d
*ctx
;
361 nouveau_notifier_free(&ctx
->ntfy
);
362 nouveau_grobj_free(&ctx
->m2mf
);
363 nouveau_grobj_free(&ctx
->surf2d
);
364 nouveau_grobj_free(&ctx
->swzsurf
);
365 nouveau_grobj_free(&ctx
->rect
);
366 nouveau_grobj_free(&ctx
->blit
);
367 nouveau_grobj_free(&ctx
->sifm
);
372 struct nv04_surface_2d
*
373 nv04_surface_2d_init(struct nouveau_screen
*screen
)
375 struct nv04_surface_2d
*ctx
= CALLOC_STRUCT(nv04_surface_2d
);
376 struct nouveau_channel
*chan
= screen
->channel
;
377 unsigned handle
= 0x88000000, class;
383 ret
= nouveau_notifier_alloc(chan
, handle
++, 1, &ctx
->ntfy
);
385 nv04_surface_2d_takedown(&ctx
);
389 ret
= nouveau_grobj_alloc(chan
, handle
++, 0x0039, &ctx
->m2mf
);
391 nv04_surface_2d_takedown(&ctx
);
395 BEGIN_RING(chan
, ctx
->m2mf
, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY
, 1);
396 OUT_RING (chan
, ctx
->ntfy
->handle
);
398 if (chan
->device
->chipset
< 0x10)
399 class = NV04_CONTEXT_SURFACES_2D
;
401 class = NV10_CONTEXT_SURFACES_2D
;
403 ret
= nouveau_grobj_alloc(chan
, handle
++, class, &ctx
->surf2d
);
405 nv04_surface_2d_takedown(&ctx
);
409 BEGIN_RING(chan
, ctx
->surf2d
,
410 NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE
, 2);
411 OUT_RING (chan
, chan
->vram
->handle
);
412 OUT_RING (chan
, chan
->vram
->handle
);
414 if (chan
->device
->chipset
< 0x10)
415 class = NV04_IMAGE_BLIT
;
417 class = NV12_IMAGE_BLIT
;
419 ret
= nouveau_grobj_alloc(chan
, handle
++, class, &ctx
->blit
);
421 nv04_surface_2d_takedown(&ctx
);
425 BEGIN_RING(chan
, ctx
->blit
, NV04_IMAGE_BLIT_DMA_NOTIFY
, 1);
426 OUT_RING (chan
, ctx
->ntfy
->handle
);
427 BEGIN_RING(chan
, ctx
->blit
, NV04_IMAGE_BLIT_SURFACE
, 1);
428 OUT_RING (chan
, ctx
->surf2d
->handle
);
429 BEGIN_RING(chan
, ctx
->blit
, NV04_IMAGE_BLIT_OPERATION
, 1);
430 OUT_RING (chan
, NV04_IMAGE_BLIT_OPERATION_SRCCOPY
);
432 ret
= nouveau_grobj_alloc(chan
, handle
++, NV04_GDI_RECTANGLE_TEXT
,
435 nv04_surface_2d_takedown(&ctx
);
439 BEGIN_RING(chan
, ctx
->rect
, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY
, 1);
440 OUT_RING (chan
, ctx
->ntfy
->handle
);
441 BEGIN_RING(chan
, ctx
->rect
, NV04_GDI_RECTANGLE_TEXT_SURFACE
, 1);
442 OUT_RING (chan
, ctx
->surf2d
->handle
);
443 BEGIN_RING(chan
, ctx
->rect
, NV04_GDI_RECTANGLE_TEXT_OPERATION
, 1);
444 OUT_RING (chan
, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY
);
445 BEGIN_RING(chan
, ctx
->rect
,
446 NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT
, 1);
447 OUT_RING (chan
, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE
);
449 switch (chan
->device
->chipset
& 0xf0) {
452 class = NV04_SWIZZLED_SURFACE
;
455 class = NV20_SWIZZLED_SURFACE
;
458 class = NV30_SWIZZLED_SURFACE
;
462 class = NV40_SWIZZLED_SURFACE
;
465 /* Famous last words: this really can't happen.. */
470 ret
= nouveau_grobj_alloc(chan
, handle
++, class, &ctx
->swzsurf
);
472 nv04_surface_2d_takedown(&ctx
);
476 switch (chan
->device
->chipset
& 0xf0) {
479 class = NV10_SCALED_IMAGE_FROM_MEMORY
;
482 class = NV30_SCALED_IMAGE_FROM_MEMORY
;
486 class = NV40_SCALED_IMAGE_FROM_MEMORY
;
489 class = NV04_SCALED_IMAGE_FROM_MEMORY
;
493 ret
= nouveau_grobj_alloc(chan
, handle
++, class, &ctx
->sifm
);
495 nv04_surface_2d_takedown(&ctx
);
499 ctx
->copy
= nv04_surface_copy
;
500 ctx
->fill
= nv04_surface_fill
;
505 nv04_surface_wrap_for_render(struct pipe_screen
*pscreen
, struct nv04_surface_2d
* eng2d
, struct nv04_surface
* ns
)
509 // printf("creating temp, flags is %i!\n", flags);
511 if(ns
->base
.usage
& PIPE_BUFFER_USAGE_DISCARD
)
513 temp_flags
= ns
->base
.usage
| PIPE_BUFFER_USAGE_GPU_READ
;
514 ns
->base
.usage
= PIPE_BUFFER_USAGE_GPU_WRITE
| NOUVEAU_BUFFER_USAGE_NO_RENDER
| PIPE_BUFFER_USAGE_DISCARD
;
518 temp_flags
= ns
->base
.usage
| PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
;
519 ns
->base
.usage
= PIPE_BUFFER_USAGE_GPU_WRITE
| NOUVEAU_BUFFER_USAGE_NO_RENDER
| PIPE_BUFFER_USAGE_GPU_READ
;
522 struct nv40_screen
* screen
= (struct nv40_screen
*)pscreen
;
523 ns
->base
.usage
= PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
;
525 struct pipe_texture templ
;
526 memset(&templ
, 0, sizeof(templ
));
527 templ
.format
= ns
->base
.texture
->format
;
528 templ
.target
= PIPE_TEXTURE_2D
;
529 templ
.width0
= ns
->base
.width
;
530 templ
.height0
= ns
->base
.height
;
532 templ
.last_level
= 0;
534 // TODO: this is probably wrong and we should specifically handle multisampling somehow once it is implemented
535 templ
.nr_samples
= ns
->base
.texture
->nr_samples
;
537 templ
.tex_usage
= ns
->base
.texture
->tex_usage
| PIPE_TEXTURE_USAGE_RENDER_TARGET
;
539 struct pipe_texture
* temp_tex
= pscreen
->texture_create(pscreen
, &templ
);
540 struct nv04_surface
* temp_ns
= (struct nv04_surface
*)pscreen
->get_tex_surface(pscreen
, temp_tex
, 0, 0, 0, temp_flags
);
541 temp_ns
->backing
= ns
;
543 if(ns
->base
.usage
& PIPE_BUFFER_USAGE_GPU_READ
)
544 eng2d
->copy(eng2d
, &temp_ns
->backing
->base
, 0, 0, &ns
->base
, 0, 0, ns
->base
.width
, ns
->base
.height
);