2 * Copyright 2007 NVIDIA, Corporation
3 * Copyright 2008 Ben Skeggs
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 #include "nv_include.h"
26 #include "nvc0_accel.h"
27 #include "nv50_texture.h"
29 #define NOUVEAU_BO(a, b, c) (NOUVEAU_BO_##a | NOUVEAU_BO_##b | NOUVEAU_BO_##c)
31 #if !defined(__AROS__)
33 NVC0AccelDownloadM2MF(PixmapPtr pspix
, int x
, int y
, int w
, int h
,
34 char *dst
, unsigned dst_pitch
)
36 ScrnInfoPtr pScrn
= xf86Screens
[pspix
->drawable
.pScreen
->myNum
];
39 NVC0AccelDownloadM2MF(PixmapPtr pspix
, int x
, int y
, int w
, int h
,
40 char *dst
, unsigned dst_pitch
,
41 HIDDT_StdPixFmt dstPixFmt
, OOP_Class
*cl
, OOP_Object
*o
)
43 ScrnInfoPtr pScrn
= globalcarddataptr
;
45 NVPtr pNv
= NVPTR(pScrn
);
46 struct nouveau_channel
*chan
= pNv
->chan
;
47 struct nouveau_bo
*bo
= nouveau_pixmap_bo(pspix
);
48 struct nouveau_grobj
*m2mf
= pNv
->NvMemFormat
;
49 #if !defined(__AROS__)
50 const int cpp
= pspix
->drawable
.bitsPerPixel
/ 8;
51 const int line_len
= w
* cpp
;
52 const int line_limit
= (128 << 10) / line_len
;
53 unsigned src_offset
= 0, src_pitch
= 0, tiled
= 1;
55 const int cpp
= pspix
->depth
> 16 ? 4 : 2;
56 const int line_len
= w
* cpp
;
57 const int line_limit
= pNv
->GART
->size
/ line_len
;
58 unsigned src_offset
= 0, src_pitch
= 0, tiled
= 1;
59 unsigned int exec
= (1 << 20) | NVC0_M2MF_EXEC_LINEAR_OUT
;
62 if (!nv50_style_tiled_pixmap(pspix
)) {
65 src_pitch
= exaGetPixmapPitch(pspix
);
66 src_offset
= (y
* src_pitch
) + (x
* cpp
);
68 exec
|= NVC0_M2MF_EXEC_LINEAR_IN
;
71 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_TILING_MODE_IN
, 5);
72 OUT_RING (chan
, bo
->tile_mode
);
73 #if !defined(__AROS__)
74 OUT_RING (chan
, pspix
->drawable
.width
* cpp
);
75 OUT_RING (chan
, pspix
->drawable
.height
);
77 OUT_RING (chan
, pspix
->width
* cpp
);
78 OUT_RING (chan
, pspix
->height
);
88 /* GART size >= 128 KiB assumed */
90 if (line_count
> line_limit
)
91 line_count
= line_limit
;
93 MARK_RING(chan
, 16, 4);
95 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_OFFSET_OUT_HIGH
, 2);
96 OUT_RELOCh(chan
, pNv
->GART
, 0, NOUVEAU_BO(GART
, GART
, WR
));
97 OUT_RELOCl(chan
, pNv
->GART
, 0, NOUVEAU_BO(GART
, GART
, WR
));
99 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_OFFSET_IN_HIGH
, 6);
100 OUT_RELOCh(chan
, bo
, src_offset
, NOUVEAU_BO(VRAM
, GART
, RD
));
101 OUT_RELOCl(chan
, bo
, src_offset
, NOUVEAU_BO(VRAM
, GART
, RD
));
102 OUT_RING (chan
, src_pitch
);
103 OUT_RING (chan
, line_len
);
104 OUT_RING (chan
, line_len
);
105 OUT_RING (chan
, line_count
);
108 BEGIN_RING(chan
, m2mf
,
109 NVC0_M2MF_TILING_POSITION_IN_X
, 2);
110 OUT_RING (chan
, x
* cpp
);
114 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_EXEC
, 1);
115 #if !defined(__AROS__)
116 OUT_RING (chan
, 0x100000 | (tiled
<< 8));
118 OUT_RING (chan
, exec
| (tiled
<< 8));
121 if (nouveau_bo_map(pNv
->GART
, NOUVEAU_BO_RD
)) {
125 src
= pNv
->GART
->map
;
127 #if !defined(__AROS__)
128 if (dst_pitch
== line_len
) {
129 memcpy(dst
, src
, dst_pitch
* line_count
);
130 dst
+= dst_pitch
* line_count
;
132 for (i
= 0; i
< line_count
; ++i
) {
133 memcpy(dst
, src
, line_len
);
140 HiddNouveauReadIntoRAM(
141 (char *)src
, line_len
,
142 dst
, dst_pitch
, dstPixFmt
,
145 dst
+= dst_pitch
* line_count
;
147 nouveau_bo_unmap(pNv
->GART
);
150 src_offset
+= line_count
* src_pitch
;
158 #if !defined(__AROS__)
160 NVC0AccelUploadM2MF(PixmapPtr pdpix
, int x
, int y
, int w
, int h
,
161 const char *src
, int src_pitch
)
163 ScrnInfoPtr pScrn
= xf86Screens
[pdpix
->drawable
.pScreen
->myNum
];
166 NVC0AccelUploadM2MF(PixmapPtr pdpix
, int x
, int y
, int w
, int h
,
167 const char *src
, int src_pitch
,
168 HIDDT_StdPixFmt srcPixFmt
, OOP_Class
*cl
, OOP_Object
*o
)
170 ScrnInfoPtr pScrn
= globalcarddataptr
;
172 NVPtr pNv
= NVPTR(pScrn
);
173 struct nouveau_channel
*chan
= pNv
->chan
;
174 struct nouveau_bo
*bo
= nouveau_pixmap_bo(pdpix
);
175 struct nouveau_grobj
*m2mf
= pNv
->NvMemFormat
;
176 #if !defined(__AROS__)
177 int cpp
= pdpix
->drawable
.bitsPerPixel
/ 8;
178 int line_len
= w
* cpp
;
179 int line_limit
= (128 << 10) / line_len
;
180 unsigned dst_offset
= 0, dst_pitch
= 0, tiled
= 1;
182 int cpp
= pdpix
->depth
> 16 ? 4 : 2;
183 int line_len
= w
* cpp
;
184 int line_limit
= pNv
->GART
->size
/ line_len
;
185 unsigned dst_offset
= 0, dst_pitch
= 0, tiled
= 1;
186 unsigned int exec
= (1 << 20) | NVC0_M2MF_EXEC_LINEAR_IN
;
189 if (!nv50_style_tiled_pixmap(pdpix
)) {
191 dst_pitch
= exaGetPixmapPitch(pdpix
);
192 dst_offset
= (y
* dst_pitch
) + (x
* cpp
);
193 #if defined(__AROS__)
194 exec
|= NVC0_M2MF_EXEC_LINEAR_OUT
;
197 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_TILING_MODE_OUT
, 5);
198 OUT_RING (chan
, bo
->tile_mode
);
199 #if !defined(__AROS__)
200 OUT_RING (chan
, pdpix
->drawable
.width
* cpp
);
201 OUT_RING (chan
, pdpix
->drawable
.height
);
203 OUT_RING (chan
, pdpix
->width
* cpp
);
204 OUT_RING (chan
, pdpix
->height
);
215 if (line_count
> line_limit
)
216 line_count
= line_limit
;
218 if (nouveau_bo_map(pNv
->GART
, NOUVEAU_BO_WR
))
220 dst
= pNv
->GART
->map
;
222 #if !defined(__AROS__)
223 if (src_pitch
== line_len
) {
224 memcpy(dst
, src
, src_pitch
* line_count
);
225 src
+= src_pitch
* line_count
;
227 for (i
= 0; i
< line_count
; i
++) {
228 memcpy(dst
, src
, line_len
);
235 HiddNouveauWriteFromRAM(
236 (APTR
)src
, src_pitch
, srcPixFmt
,
240 src
+= src_pitch
* line_count
;
242 nouveau_bo_unmap(pNv
->GART
);
244 if (MARK_RING(chan
, 16, 4))
247 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_OFFSET_IN_HIGH
, 2);
248 OUT_RELOCh(chan
, pNv
->GART
, 0, NOUVEAU_BO(GART
, GART
, RD
));
249 OUT_RELOCl(chan
, pNv
->GART
, 0, NOUVEAU_BO(GART
, GART
, RD
));
251 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_OFFSET_OUT_HIGH
, 2);
252 OUT_RELOCh(chan
, bo
, dst_offset
, NOUVEAU_BO(VRAM
, GART
, WR
));
253 OUT_RELOCl(chan
, bo
, dst_offset
, NOUVEAU_BO(VRAM
, GART
, WR
));
256 BEGIN_RING(chan
, m2mf
,
257 NVC0_M2MF_TILING_POSITION_OUT_X
, 2);
258 OUT_RING (chan
, x
* cpp
);
262 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_PITCH_IN
, 4);
263 OUT_RING (chan
, line_len
);
264 OUT_RING (chan
, dst_pitch
);
265 OUT_RING (chan
, line_len
);
266 OUT_RING (chan
, line_count
);
268 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_EXEC
, 1);
269 #if !defined(__AROS__)
270 OUT_RING (chan
, 0x100000 | (tiled
<< 4));
272 OUT_RING (chan
, exec
| (tiled
<< 4));
277 dst_offset
+= line_count
* dst_pitch
;
285 #if !defined(__AROS__)
286 struct nvc0_exa_state
{
288 PictTransformPtr transform
;
296 static struct nvc0_exa_state exa_state
;
299 #if !defined(__AROS__)
300 #define NVC0EXA_LOCALS(p) \
301 ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \
302 NVPtr pNv = NVPTR(pScrn); \
303 struct nouveau_channel *chan = pNv->chan; (void)chan; \
304 struct nouveau_grobj *m2mf = pNv->NvMemFormat; (void)m2mf; \
305 struct nouveau_grobj *eng2d = pNv->Nv2D; (void)eng2d; \
306 struct nouveau_grobj *fermi = pNv->Nv3D; (void)fermi; \
307 struct nvc0_exa_state *state = &exa_state; (void)state
309 #define NVC0EXA_LOCALS(p) \
310 ScrnInfoPtr pScrn = globalcarddataptr; \
311 NVPtr pNv = NVPTR(pScrn); \
312 struct nouveau_channel *chan = pNv->chan; (void)chan; \
313 struct nouveau_grobj *m2mf = pNv->NvMemFormat; (void)m2mf; \
314 struct nouveau_grobj *eng2d = pNv->Nv2D; (void)eng2d; \
315 struct nouveau_grobj *fermi = pNv->Nv3D; (void)fermi;
318 #if !defined(__AROS__)
319 #define BF(f) NV50_BLEND_FACTOR_##f
321 struct nvc0_blend_op
{
328 static struct nvc0_blend_op
330 /* Clear */ { 0, 0, BF( ZERO
), BF( ZERO
) },
331 /* Src */ { 0, 0, BF( ONE
), BF( ZERO
) },
332 /* Dst */ { 0, 0, BF( ZERO
), BF( ONE
) },
333 /* Over */ { 1, 0, BF( ONE
), BF(ONE_MINUS_SRC_ALPHA
) },
334 /* OverReverse */ { 0, 1, BF(ONE_MINUS_DST_ALPHA
), BF( ONE
) },
335 /* In */ { 0, 1, BF( DST_ALPHA
), BF( ZERO
) },
336 /* InReverse */ { 1, 0, BF( ZERO
), BF( SRC_ALPHA
) },
337 /* Out */ { 0, 1, BF(ONE_MINUS_DST_ALPHA
), BF( ZERO
) },
338 /* OutReverse */ { 1, 0, BF( ZERO
), BF(ONE_MINUS_SRC_ALPHA
) },
339 /* Atop */ { 1, 1, BF( DST_ALPHA
), BF(ONE_MINUS_SRC_ALPHA
) },
340 /* AtopReverse */ { 1, 1, BF(ONE_MINUS_DST_ALPHA
), BF( SRC_ALPHA
) },
341 /* Xor */ { 1, 1, BF(ONE_MINUS_DST_ALPHA
), BF(ONE_MINUS_SRC_ALPHA
) },
342 /* Add */ { 0, 0, BF( ONE
), BF( ONE
) },
347 NVC0EXA2DSurfaceFormat(PixmapPtr ppix
, uint32_t *fmt
)
349 NVC0EXA_LOCALS(ppix
);
351 #if !defined(__AROS__)
352 switch (ppix
->drawable
.bitsPerPixel
) {
354 switch (ppix
->depth
) {
356 case 8 : *fmt
= NV50_2D_SRC_FORMAT_R8_UNORM
; break;
357 case 15: *fmt
= NV50_2D_SRC_FORMAT_X1R5G5B5_UNORM
; break;
358 case 16: *fmt
= NV50_2D_SRC_FORMAT_R5G6B5_UNORM
; break;
359 case 24: *fmt
= NV50_2D_SRC_FORMAT_X8R8G8B8_UNORM
; break;
360 case 30: *fmt
= NV50_2D_SRC_FORMAT_A2B10G10R10_UNORM
; break;
361 case 32: *fmt
= NV50_2D_SRC_FORMAT_A8R8G8B8_UNORM
; break;
363 NOUVEAU_FALLBACK("Unknown surface format for bpp=%d\n",
364 ppix
->drawable
.bitsPerPixel
);
371 static void NVC0EXASetClip(PixmapPtr ppix
, int x
, int y
, int w
, int h
)
373 NVC0EXA_LOCALS(ppix
);
375 BEGIN_RING(chan
, eng2d
, NV50_2D_CLIP_X
, 4);
383 NVC0EXAAcquireSurface2D(PixmapPtr ppix
, int is_src
)
385 NVC0EXA_LOCALS(ppix
);
386 struct nouveau_bo
*bo
= nouveau_pixmap_bo(ppix
);
387 int mthd
= is_src
? NV50_2D_SRC_FORMAT
: NV50_2D_DST_FORMAT
;
388 uint32_t fmt
, bo_flags
;
390 if (!NVC0EXA2DSurfaceFormat(ppix
, &fmt
))
393 bo_flags
= NOUVEAU_BO_VRAM
;
394 bo_flags
|= is_src
? NOUVEAU_BO_RD
: NOUVEAU_BO_WR
;
396 if (!nv50_style_tiled_pixmap(ppix
)) {
397 BEGIN_RING(chan
, eng2d
, mthd
, 2);
398 OUT_RING (chan
, fmt
);
400 BEGIN_RING(chan
, eng2d
, mthd
+ 0x14, 1);
401 OUT_RING (chan
, (uint32_t)exaGetPixmapPitch(ppix
));
403 BEGIN_RING(chan
, eng2d
, mthd
, 5);
404 OUT_RING (chan
, fmt
);
406 OUT_RING (chan
, bo
->tile_mode
);
411 BEGIN_RING(chan
, eng2d
, mthd
+ 0x18, 4);
412 #if !defined(__AROS__)
413 OUT_RING (chan
, ppix
->drawable
.width
);
414 OUT_RING (chan
, ppix
->drawable
.height
);
416 OUT_RING (chan
, ppix
->width
);
417 OUT_RING (chan
, ppix
->height
);
419 if (OUT_RELOCh(chan
, bo
, 0, bo_flags
) ||
420 OUT_RELOCl(chan
, bo
, 0, bo_flags
))
424 #if !defined(__AROS__)
425 NVC0EXASetClip(ppix
, 0, 0, ppix
->drawable
.width
, ppix
->drawable
.height
);
427 NVC0EXASetClip(ppix
, 0, 0, ppix
->width
, ppix
->height
);
434 NVC0EXASetPattern(PixmapPtr pdpix
, int col0
, int col1
, int pat0
, int pat1
)
436 NVC0EXA_LOCALS(pdpix
);
438 BEGIN_RING(chan
, eng2d
, NV50_2D_PATTERN_COLOR(0), 4);
439 OUT_RING (chan
, col0
);
440 OUT_RING (chan
, col1
);
441 OUT_RING (chan
, pat0
);
442 OUT_RING (chan
, pat1
);
445 #if !defined(__AROS__)
447 NVC0EXASetROP(PixmapPtr pdpix
, int alu
, Pixel planemask
)
449 NVC0EXA_LOCALS(pdpix
);
453 rop
= NVROP
[alu
].copy_planemask
;
455 rop
= NVROP
[alu
].copy
;
457 BEGIN_RING(chan
, eng2d
, NV50_2D_OPERATION
, 1);
458 if (alu
== GXcopy
&& EXA_PM_IS_SOLID(&pdpix
->drawable
, planemask
)) {
459 OUT_RING (chan
, NV50_2D_OPERATION_SRCCOPY
);
462 OUT_RING (chan
, NV50_2D_OPERATION_SRCCOPY_PREMULT
);
465 BEGIN_RING(chan
, eng2d
, NV50_2D_PATTERN_FORMAT
, 2);
466 switch (pdpix
->drawable
.bitsPerPixel
) {
467 case 8: OUT_RING (chan
, 3); break;
468 case 15: OUT_RING (chan
, 1); break;
469 case 16: OUT_RING (chan
, 0); break;
478 /* There are 16 ALUs.
480 * 16-31: copy_planemask
483 if (!EXA_PM_IS_SOLID(&pdpix
->drawable
, planemask
)) {
485 NVC0EXASetPattern(pdpix
, 0, planemask
, ~0, ~0);
487 if (pNv
->currentRop
> 15)
488 NVC0EXASetPattern(pdpix
, ~0, ~0, ~0, ~0);
491 if (pNv
->currentRop
!= alu
) {
492 BEGIN_RING(chan
, eng2d
, NV50_2D_ROP
, 1);
493 OUT_RING (chan
, rop
);
494 pNv
->currentRop
= alu
;
499 NVC0EXASetROP(PixmapPtr pdpix
, int alu
, Pixel planemask
)
501 NVC0EXA_LOCALS(pdpix
);
504 rop
= NVROP
[alu
].copy
;
506 BEGIN_RING(chan
, eng2d
, NV50_2D_OPERATION
, 1);
507 if (alu
== 0x03 /* DrawMode_Copy */) {
508 OUT_RING (chan
, NV50_2D_OPERATION_SRCCOPY
);
511 OUT_RING (chan
, NV50_2D_OPERATION_SRCCOPY_PREMULT
);
514 BEGIN_RING(chan
, eng2d
, NV50_2D_PATTERN_FORMAT
, 2);
515 switch (pdpix
->depth
) {
516 case 8: OUT_RING (chan
, 3); break;
517 case 15: OUT_RING (chan
, 1); break;
518 case 16: OUT_RING (chan
, 0); break;
527 BEGIN_RING(chan
, eng2d
, NV50_2D_ROP
, 1);
528 OUT_RING (chan
, rop
);
532 #if !defined(__AROS__)
534 NVC0EXAStateSolidResubmit(struct nouveau_channel
*chan
)
536 ScrnInfoPtr pScrn
= chan
->user_private
;
537 NVPtr pNv
= NVPTR(pScrn
);
539 NVC0EXAPrepareSolid(pNv
->pdpix
, pNv
->alu
, pNv
->planemask
,
545 NVC0EXAPrepareSolid(PixmapPtr pdpix
, int alu
, Pixel planemask
, Pixel fg
)
547 NVC0EXA_LOCALS(pdpix
);
550 if (!NVC0EXA2DSurfaceFormat(pdpix
, &fmt
))
551 NOUVEAU_FALLBACK("rect format\n");
553 if (MARK_RING(chan
, 64, 4))
554 NOUVEAU_FALLBACK("ring space\n");
556 if (!NVC0EXAAcquireSurface2D(pdpix
, 0)) {
558 NOUVEAU_FALLBACK("dest pixmap\n");
561 NVC0EXASetROP(pdpix
, alu
, planemask
);
563 BEGIN_RING(chan
, eng2d
, NV50_2D_DRAW_SHAPE
, 3);
564 OUT_RING (chan
, NV50_2D_DRAW_SHAPE_RECTANGLES
);
565 OUT_RING (chan
, fmt
);
568 #if !defined(__AROS__)
571 pNv
->planemask
= planemask
;
573 chan
->flush_notify
= NVC0EXAStateSolidResubmit
;
575 chan
->flush_notify
= NULL
;
581 NVC0EXASolid(PixmapPtr pdpix
, int x1
, int y1
, int x2
, int y2
)
583 NVC0EXA_LOCALS(pdpix
);
586 BEGIN_RING(chan
, eng2d
, NV50_2D_DRAW_POINT32_X(0), 4);
592 #if !defined(__AROS__)
593 if ((x2
- x1
) * (y2
- y1
) >= 512)
598 #if !defined(__AROS__)
600 NVC0EXADoneSolid(PixmapPtr pdpix
)
602 NVC0EXA_LOCALS(pdpix
);
604 chan
->flush_notify
= NULL
;
608 NVC0EXAStateCopyResubmit(struct nouveau_channel
*chan
)
610 ScrnInfoPtr pScrn
= chan
->user_private
;
611 NVPtr pNv
= NVPTR(pScrn
);
613 NVC0EXAPrepareCopy(pNv
->pspix
, pNv
->pdpix
, 0, 0, pNv
->alu
,
619 NVC0EXAPrepareCopy(PixmapPtr pspix
, PixmapPtr pdpix
, int dx
, int dy
,
620 int alu
, Pixel planemask
)
622 NVC0EXA_LOCALS(pdpix
);
624 if (MARK_RING(chan
, 64, 4))
625 NOUVEAU_FALLBACK("ring space\n");
627 if (!NVC0EXAAcquireSurface2D(pspix
, 1)) {
629 NOUVEAU_FALLBACK("src pixmap\n");
632 if (!NVC0EXAAcquireSurface2D(pdpix
, 0)) {
634 NOUVEAU_FALLBACK("dest pixmap\n");
637 NVC0EXASetROP(pdpix
, alu
, planemask
);
639 #if !defined(__AROS__)
643 pNv
->planemask
= planemask
;
644 chan
->flush_notify
= NVC0EXAStateCopyResubmit
;
646 chan
->flush_notify
= NULL
;
652 NVC0EXACopy(PixmapPtr pdpix
, int srcX
, int srcY
,
654 int width
, int height
)
656 NVC0EXA_LOCALS(pdpix
);
658 WAIT_RING (chan
, 17);
659 BEGIN_RING(chan
, eng2d
, NV50_2D_SERIALIZE
, 1);
661 BEGIN_RING(chan
, eng2d
, 0x088c, 1);
663 BEGIN_RING(chan
, eng2d
, NV50_2D_BLIT_DST_X
, 12);
664 OUT_RING (chan
, dstX
);
665 OUT_RING (chan
, dstY
);
666 OUT_RING (chan
, width
);
667 OUT_RING (chan
, height
);
668 OUT_RING (chan
, 0); /* DU,V_DX,Y_FRACT,INT */
672 OUT_RING (chan
, 0); /* BLIT_SRC_X,Y_FRACT,INT */
673 OUT_RING (chan
, srcX
);
675 OUT_RING (chan
, srcY
);
677 #if !defined(__AROS__)
678 if (width
* height
>= 512)
683 #if !defined(__AROS__)
685 NVC0EXADoneCopy(PixmapPtr pdpix
)
687 NVC0EXA_LOCALS(pdpix
);
689 chan
->flush_notify
= NULL
;
693 NVC0EXAStateSIFCResubmit(struct nouveau_channel
*chan
)
695 ScrnInfoPtr pScrn
= chan
->user_private
;
696 NVPtr pNv
= NVPTR(pScrn
);
698 if (MARK_RING(pNv
->chan
, 32, 2))
701 if (!NVC0EXAAcquireSurface2D(pNv
->pdpix
, 0))
702 MARK_UNDO(pNv
->chan
);
706 NVC0EXAUploadSIFC(const char *src
, int src_pitch
,
707 PixmapPtr pdpix
, int x
, int y
, int w
, int h
, int cpp
)
709 NVC0EXA_LOCALS(pdpix
);
710 ScreenPtr pScreen
= pdpix
->drawable
.pScreen
;
711 int line_dwords
= (w
* cpp
+ 3) / 4;
714 if (!NVC0EXA2DSurfaceFormat(pdpix
, &sifc_fmt
))
715 NOUVEAU_FALLBACK("hostdata format\n");
717 if (MARK_RING(chan
, 64, 2))
720 if (!NVC0EXAAcquireSurface2D(pdpix
, 0)) {
722 NOUVEAU_FALLBACK("dest pixmap\n");
725 /* If the pitch isn't aligned to a dword you can
726 * get corruption at the end of a line.
728 NVC0EXASetClip(pdpix
, x
, y
, w
, h
);
730 BEGIN_RING(chan
, eng2d
, NV50_2D_OPERATION
, 1);
731 OUT_RING (chan
, NV50_2D_OPERATION_SRCCOPY
);
732 BEGIN_RING(chan
, eng2d
, NV50_2D_SIFC_BITMAP_ENABLE
, 2);
734 OUT_RING (chan
, sifc_fmt
);
735 BEGIN_RING(chan
, eng2d
, NV50_2D_SIFC_WIDTH
, 10);
736 OUT_RING (chan
, (line_dwords
* 4) / cpp
);
738 OUT_RING (chan
, 0); /* SIFC_DX,Y_DU,V_FRACT,INT */
742 OUT_RING (chan
, 0); /* SIFC_DST_X,Y_FRACT,INT */
748 chan
->flush_notify
= NVC0EXAStateSIFCResubmit
;
751 const char *ptr
= src
;
752 int count
= line_dwords
;
755 int size
= count
> 1792 ? 1792 : count
;
757 WAIT_RING (chan
, size
+ 1);
758 BEGIN_RING_NI(chan
, eng2d
, NV50_2D_SIFC_DATA
, size
);
759 OUT_RINGp (chan
, ptr
, size
);
768 chan
->flush_notify
= NULL
;
770 if (pdpix
== pScreen
->GetScreenPixmap(pScreen
))
776 NVC0EXACheckRenderTarget(PicturePtr ppict
)
778 if (ppict
->pDrawable
->width
> 8192 ||
779 ppict
->pDrawable
->height
> 8192)
780 NOUVEAU_FALLBACK("render target dimensions exceeded %dx%d\n",
781 ppict
->pDrawable
->width
,
782 ppict
->pDrawable
->height
);
784 switch (ppict
->format
) {
792 case PICT_a2b10g10r10
:
793 case PICT_x2b10g10r10
:
794 case PICT_a2r10g10b10
:
795 case PICT_x2r10g10b10
:
798 NOUVEAU_FALLBACK("picture format 0x%08x\n", ppict
->format
);
805 NVC0EXARenderTarget(PixmapPtr ppix
, PicturePtr ppict
)
807 NVC0EXA_LOCALS(ppix
);
808 struct nouveau_bo
*bo
= nouveau_pixmap_bo(ppix
);
811 /*XXX: Scanout buffer not tiled, someone needs to figure it out */
812 if (!nv50_style_tiled_pixmap(ppix
))
813 NOUVEAU_FALLBACK("pixmap is scanout buffer\n");
815 switch (ppict
->format
) {
816 case PICT_a8r8g8b8
: format
= NV50_SURFACE_FORMAT_A8R8G8B8_UNORM
; break;
817 case PICT_x8r8g8b8
: format
= NV50_SURFACE_FORMAT_X8R8G8B8_UNORM
; break;
818 case PICT_r5g6b5
: format
= NV50_SURFACE_FORMAT_R5G6B5_UNORM
; break;
819 case PICT_a8
: format
= NV50_SURFACE_FORMAT_A8_UNORM
; break;
820 case PICT_x1r5g5b5
: format
= NV50_SURFACE_FORMAT_X1R5G5B5_UNORM
; break;
821 case PICT_a1r5g5b5
: format
= NV50_SURFACE_FORMAT_A1R5G5B5_UNORM
; break;
822 case PICT_x8b8g8r8
: format
= NV50_SURFACE_FORMAT_X8B8G8R8_UNORM
; break;
823 case PICT_a2b10g10r10
:
824 case PICT_x2b10g10r10
:
825 format
= NV50_SURFACE_FORMAT_A2B10G10R10_UNORM
;
827 case PICT_a2r10g10b10
:
828 case PICT_x2r10g10b10
:
829 format
= NV50_SURFACE_FORMAT_A2R10G10B10_UNORM
;
832 NOUVEAU_FALLBACK("invalid picture format\n");
835 BEGIN_RING(chan
, fermi
, NVC0_3D_RT_ADDRESS_HIGH(0), 8);
836 if (OUT_RELOCh(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
) ||
837 OUT_RELOCl(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
))
839 OUT_RING (chan
, ppix
->drawable
.width
);
840 OUT_RING (chan
, ppix
->drawable
.height
);
841 OUT_RING (chan
, format
);
842 OUT_RING (chan
, bo
->tile_mode
);
843 OUT_RING (chan
, 0x00000001);
844 OUT_RING (chan
, 0x00000000);
850 NVC0EXACheckTexture(PicturePtr ppict
, PicturePtr pdpict
, int op
)
852 if (!ppict
->pDrawable
)
853 NOUVEAU_FALLBACK("Solid and gradient pictures unsupported.\n");
855 if (ppict
->pDrawable
->width
> 8192 ||
856 ppict
->pDrawable
->height
> 8192)
857 NOUVEAU_FALLBACK("texture dimensions exceeded %dx%d\n",
858 ppict
->pDrawable
->width
,
859 ppict
->pDrawable
->height
);
861 switch (ppict
->format
) {
875 case PICT_a2b10g10r10
:
876 case PICT_x2b10g10r10
:
877 case PICT_x2r10g10b10
:
878 case PICT_a2r10g10b10
:
885 NOUVEAU_FALLBACK("picture format 0x%08x\n", ppict
->format
);
888 switch (ppict
->filter
) {
889 case PictFilterNearest
:
890 case PictFilterBilinear
:
893 NOUVEAU_FALLBACK("picture filter %d\n", ppict
->filter
);
896 /* OpenGL and Render disagree on what should be sampled outside an XRGB
897 * texture (with no repeating). Opengl has a hardcoded alpha value of
898 * 1.0, while render expects 0.0. We assume that clipping is done for
899 * untranformed sources.
901 if (NVC0EXABlendOp
[op
].src_alpha
&& !ppict
->repeat
&&
902 ppict
->transform
&& (PICT_FORMAT_A(ppict
->format
) == 0)
903 && (PICT_FORMAT_A(pdpict
->format
) != 0))
904 NOUVEAU_FALLBACK("REPEAT_NONE unsupported for XRGB source\n");
909 #define _(X1, X2, X3, X4, FMT) \
910 (NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_TYPEG_UNORM | \
911 NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_TYPEA_UNORM | \
912 NV50TIC_0_0_MAP##X1 | NV50TIC_0_0_MAP##X2 | \
913 NV50TIC_0_0_MAP##X3 | NV50TIC_0_0_MAP##X4 | \
914 NV50TIC_0_0_FMT_##FMT)
917 NVC0EXATexture(PixmapPtr ppix
, PicturePtr ppict
, unsigned unit
)
919 NVC0EXA_LOCALS(ppix
);
920 struct nouveau_bo
*bo
= nouveau_pixmap_bo(ppix
);
921 const unsigned tcb_flags
= NOUVEAU_BO_RDWR
| NOUVEAU_BO_VRAM
;
924 /* XXX: maybe add support for linear textures at some point */
925 if (!nv50_style_tiled_pixmap(ppix
))
926 NOUVEAU_FALLBACK("pixmap is scanout buffer\n");
928 BEGIN_RING(chan
, fermi
, NVC0_3D_TIC_ADDRESS_HIGH
, 3);
929 if (OUT_RELOCh(chan
, pNv
->tesla_scratch
, TIC_OFFSET
, tcb_flags
) ||
930 OUT_RELOCl(chan
, pNv
->tesla_scratch
, TIC_OFFSET
, tcb_flags
))
934 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_OFFSET_OUT_HIGH
, 2);
935 if (OUT_RELOCh(chan
, pNv
->tesla_scratch
,
936 TIC_OFFSET
+ unit
* 32, tcb_flags
) ||
937 OUT_RELOCl(chan
, pNv
->tesla_scratch
,
938 TIC_OFFSET
+ unit
* 32, tcb_flags
))
940 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_LINE_LENGTH_IN
, 2);
941 OUT_RING (chan
, 8 * 4);
943 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_EXEC
, 1);
944 OUT_RING (chan
, 0x100111);
945 BEGIN_RING_NI(chan
, m2mf
, NVC0_M2MF_DATA
, 8);
947 switch (ppict
->format
) {
949 OUT_RING(chan
, _(B_C0
, G_C1
, R_C2
, A_C3
, 8_8_8_8
));
952 OUT_RING(chan
, _(R_C0
, G_C1
, B_C2
, A_C3
, 8_8_8_8
));
955 OUT_RING(chan
, _(B_C0
, G_C1
, R_C2
, A_ONE
, 8_8_8_8
));
958 OUT_RING(chan
, _(R_C0
, G_C1
, B_C2
, A_ONE
, 8_8_8_8
));
961 OUT_RING(chan
, _(B_C0
, G_C1
, R_C2
, A_ONE
, 5_6_5
));
964 OUT_RING(chan
, _(A_C0
, B_ZERO
, G_ZERO
, R_ZERO
, 8));
967 OUT_RING(chan
, _(B_C0
, G_C1
, R_C2
, A_ONE
, 1_5_5_5
));
970 OUT_RING(chan
, _(R_C0
, G_C1
, B_C2
, A_ONE
, 1_5_5_5
));
973 OUT_RING(chan
, _(B_C0
, G_C1
, R_C2
, A_C3
, 1_5_5_5
));
976 OUT_RING(chan
, _(R_C0
, G_C1
, B_C2
, A_C3
, 1_5_5_5
));
979 OUT_RING(chan
, _(R_C0
, G_C1
, B_C2
, A_ONE
, 5_6_5
));
982 OUT_RING(chan
, _(A_ONE
, R_C1
, G_C2
, B_C3
, 8_8_8_8
));
985 OUT_RING(chan
, _(A_C0
, R_C1
, G_C2
, B_C3
, 8_8_8_8
));
987 case PICT_a2b10g10r10
:
988 OUT_RING(chan
, _(R_C0
, G_C1
, B_C2
, A_C3
, 2_10_10_10
));
990 case PICT_x2b10g10r10
:
991 OUT_RING(chan
, _(R_C0
, G_C1
, B_C2
, A_ONE
, 2_10_10_10
));
993 case PICT_x2r10g10b10
:
994 OUT_RING(chan
, _(B_C0
, G_C1
, R_C2
, A_ONE
, 2_10_10_10
));
996 case PICT_a2r10g10b10
:
997 OUT_RING(chan
, _(B_C0
, G_C1
, R_C2
, A_C3
, 2_10_10_10
));
1000 OUT_RING(chan
, _(B_C0
, G_C1
, R_C2
, A_ONE
, 4_4_4_4
));
1003 OUT_RING(chan
, _(R_C0
, G_C1
, B_C2
, A_ONE
, 4_4_4_4
));
1006 OUT_RING(chan
, _(B_C0
, G_C1
, R_C2
, A_C3
, 4_4_4_4
));
1009 OUT_RING(chan
, _(R_C0
, G_C1
, B_C2
, A_C3
, 4_4_4_4
));
1012 NOUVEAU_FALLBACK("invalid picture format, this SHOULD NOT HAPPEN. Expect trouble.\n");
1016 mode
= 0xd0005000 | (bo
->tile_mode
<< (22 - 4));
1017 if (OUT_RELOCl(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
) ||
1018 OUT_RELOCd(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
|
1019 NOUVEAU_BO_HIGH
| NOUVEAU_BO_OR
, mode
, mode
))
1021 OUT_RING (chan
, 0x00300000);
1022 OUT_RING (chan
, (1 << 31) | ppix
->drawable
.width
);
1023 OUT_RING (chan
, (1 << 16) | ppix
->drawable
.height
);
1024 OUT_RING (chan
, 0x03000000);
1025 OUT_RING (chan
, 0x00000000);
1027 BEGIN_RING(chan
, fermi
, NVC0_3D_TSC_ADDRESS_HIGH
, 3);
1028 if (OUT_RELOCh(chan
, pNv
->tesla_scratch
, TSC_OFFSET
, tcb_flags
) ||
1029 OUT_RELOCl(chan
, pNv
->tesla_scratch
, TSC_OFFSET
, tcb_flags
))
1033 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_OFFSET_OUT_HIGH
, 2);
1034 if (OUT_RELOCh(chan
, pNv
->tesla_scratch
,
1035 TSC_OFFSET
+ unit
* 32, tcb_flags
) ||
1036 OUT_RELOCl(chan
, pNv
->tesla_scratch
,
1037 TSC_OFFSET
+ unit
* 32, tcb_flags
))
1039 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_LINE_LENGTH_IN
, 2);
1040 OUT_RING (chan
, 8 * 4);
1042 BEGIN_RING(chan
, m2mf
, NVC0_M2MF_EXEC
, 1);
1043 OUT_RING (chan
, 0x100111);
1044 BEGIN_RING_NI(chan
, m2mf
, NVC0_M2MF_DATA
, 8);
1046 if (ppict
->repeat
) {
1047 switch (ppict
->repeatType
) {
1049 OUT_RING (chan
, 0x00024000 |
1050 NV50TSC_1_0_WRAPS_CLAMP
|
1051 NV50TSC_1_0_WRAPT_CLAMP
|
1052 NV50TSC_1_0_WRAPR_CLAMP
);
1055 OUT_RING (chan
, 0x00024000 |
1056 NV50TSC_1_0_WRAPS_MIRROR_REPEAT
|
1057 NV50TSC_1_0_WRAPT_MIRROR_REPEAT
|
1058 NV50TSC_1_0_WRAPR_MIRROR_REPEAT
);
1062 OUT_RING (chan
, 0x00024000 |
1063 NV50TSC_1_0_WRAPS_REPEAT
|
1064 NV50TSC_1_0_WRAPT_REPEAT
|
1065 NV50TSC_1_0_WRAPR_REPEAT
);
1069 OUT_RING (chan
, 0x00024000 |
1070 NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER
|
1071 NV50TSC_1_0_WRAPT_CLAMP_TO_BORDER
|
1072 NV50TSC_1_0_WRAPR_CLAMP_TO_BORDER
);
1074 if (ppict
->filter
== PictFilterBilinear
) {
1076 NV50TSC_1_1_MAGF_LINEAR
|
1077 NV50TSC_1_1_MINF_LINEAR
| NV50TSC_1_1_MIPF_NONE
);
1080 NV50TSC_1_1_MAGF_NEAREST
|
1081 NV50TSC_1_1_MINF_NEAREST
| NV50TSC_1_1_MIPF_NONE
);
1083 OUT_RING (chan
, 0x00000000);
1084 OUT_RING (chan
, 0x00000000);
1085 OUT_RINGf (chan
, 0.0f
);
1086 OUT_RINGf (chan
, 0.0f
);
1087 OUT_RINGf (chan
, 0.0f
);
1088 OUT_RINGf (chan
, 0.0f
);
1090 state
->unit
[unit
].width
= ppix
->drawable
.width
;
1091 state
->unit
[unit
].height
= ppix
->drawable
.height
;
1092 state
->unit
[unit
].transform
= ppict
->transform
;
1097 NVC0EXACheckBlend(int op
)
1100 NOUVEAU_FALLBACK("unsupported blend op %d\n", op
);
1105 NVC0EXABlend(PixmapPtr ppix
, PicturePtr ppict
, int op
, int component_alpha
)
1107 NVC0EXA_LOCALS(ppix
);
1108 struct nvc0_blend_op
*b
= &NVC0EXABlendOp
[op
];
1109 unsigned sblend
= b
->src_blend
;
1110 unsigned dblend
= b
->dst_blend
;
1113 if (!PICT_FORMAT_A(ppict
->format
)) {
1114 if (sblend
== BF(DST_ALPHA
))
1117 if (sblend
== BF(ONE_MINUS_DST_ALPHA
))
1122 if (b
->src_alpha
&& component_alpha
) {
1123 if (dblend
== BF(SRC_ALPHA
))
1124 dblend
= BF(SRC_COLOR
);
1126 if (dblend
== BF(ONE_MINUS_SRC_ALPHA
))
1127 dblend
= BF(ONE_MINUS_SRC_COLOR
);
1130 if (sblend
== BF(ONE
) && dblend
== BF(ZERO
)) {
1131 BEGIN_RING(chan
, fermi
, NVC0_3D_BLEND_ENABLE(0), 1);
1134 BEGIN_RING(chan
, fermi
, NVC0_3D_BLEND_ENABLE(0), 1);
1136 BEGIN_RING(chan
, fermi
, NVC0_3D_BLEND_EQUATION_RGB
, 5);
1137 OUT_RING (chan
, NVC0_3D_BLEND_EQUATION_RGB_FUNC_ADD
);
1138 OUT_RING (chan
, sblend
);
1139 OUT_RING (chan
, dblend
);
1140 OUT_RING (chan
, NVC0_3D_BLEND_EQUATION_ALPHA_FUNC_ADD
);
1141 OUT_RING (chan
, sblend
);
1142 BEGIN_RING(chan
, fermi
, NVC0_3D_BLEND_FUNC_DST_ALPHA
, 1);
1143 OUT_RING (chan
, dblend
);
1148 NVC0EXACheckComposite(int op
,
1149 PicturePtr pspict
, PicturePtr pmpict
, PicturePtr pdpict
)
1151 if (!NVC0EXACheckBlend(op
))
1152 NOUVEAU_FALLBACK("blend not supported\n");
1154 if (!NVC0EXACheckRenderTarget(pdpict
))
1155 NOUVEAU_FALLBACK("render target invalid\n");
1157 if (!NVC0EXACheckTexture(pspict
, pdpict
, op
))
1158 NOUVEAU_FALLBACK("src picture invalid\n");
1161 if (pmpict
->componentAlpha
&&
1162 PICT_FORMAT_RGB(pmpict
->format
) &&
1163 NVC0EXABlendOp
[op
].src_alpha
&&
1164 NVC0EXABlendOp
[op
].src_blend
!= BF(ZERO
))
1165 NOUVEAU_FALLBACK("component-alpha not supported\n");
1167 if (!NVC0EXACheckTexture(pmpict
, pdpict
, op
))
1168 NOUVEAU_FALLBACK("mask picture invalid\n");
1175 NVC0EXAStateCompositeResubmit(struct nouveau_channel
*chan
)
1177 ScrnInfoPtr pScrn
= chan
->user_private
;
1178 NVPtr pNv
= NVPTR(pScrn
);
1180 NVC0EXAPrepareComposite(pNv
->alu
, pNv
->pspict
, pNv
->pmpict
, pNv
->pdpict
,
1181 pNv
->pspix
, pNv
->pmpix
, pNv
->pdpix
);
1185 NVC0EXAPrepareComposite(int op
,
1186 PicturePtr pspict
, PicturePtr pmpict
, PicturePtr pdpict
,
1187 PixmapPtr pspix
, PixmapPtr pmpix
, PixmapPtr pdpix
)
1189 NVC0EXA_LOCALS(pspix
);
1190 const unsigned shd_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
;
1192 if (MARK_RING (chan
, 128, 4 + 2 + 2 * 10))
1193 NOUVEAU_FALLBACK("ring space\n");
1195 // fonts: !pmpict, op == 12 (Add, ONE/ONE)
1197 if (pmpict || op != 12)
1198 NOUVEAU_FALLBACK("comp-alpha");
1201 BEGIN_RING(chan
, eng2d
, NV50_2D_SERIALIZE
, 1);
1204 if (!NVC0EXARenderTarget(pdpix
, pdpict
)) {
1206 NOUVEAU_FALLBACK("render target invalid\n");
1209 NVC0EXABlend(pdpix
, pdpict
, op
, pmpict
&& pmpict
->componentAlpha
&&
1210 PICT_FORMAT_RGB(pmpict
->format
));
1212 BEGIN_RING(chan
, fermi
, NVC0_3D_CODE_ADDRESS_HIGH
, 2);
1213 if (OUT_RELOCh(chan
, pNv
->tesla_scratch
, CODE_OFFSET
, shd_flags
) ||
1214 OUT_RELOCl(chan
, pNv
->tesla_scratch
, CODE_OFFSET
, shd_flags
)) {
1219 if (!NVC0EXATexture(pspix
, pspict
, 0)) {
1221 NOUVEAU_FALLBACK("src picture invalid\n");
1223 BEGIN_RING(chan
, fermi
, NVC0_3D_BIND_TIC(4), 1);
1224 OUT_RING (chan
, (0 << 9) | (0 << 1) | NVC0_3D_BIND_TIC_ACTIVE
);
1227 if (!NVC0EXATexture(pmpix
, pmpict
, 1)) {
1229 NOUVEAU_FALLBACK("mask picture invalid\n");
1231 state
->have_mask
= TRUE
;
1233 BEGIN_RING(chan
, fermi
, NVC0_3D_BIND_TIC(4), 1);
1234 OUT_RING (chan
, (1 << 9) | (1 << 1) | NVC0_3D_BIND_TIC_ACTIVE
);
1236 BEGIN_RING(chan
, fermi
, NVC0_3D_SP_START_ID(5), 1);
1237 if (pdpict
->format
== PICT_a8
) {
1238 OUT_RING (chan
, PFP_C_A8
);
1240 if (pmpict
->componentAlpha
&&
1241 PICT_FORMAT_RGB(pmpict
->format
)) {
1242 if (NVC0EXABlendOp
[op
].src_alpha
)
1243 OUT_RING (chan
, PFP_CCASA
);
1245 OUT_RING (chan
, PFP_CCA
);
1247 OUT_RING (chan
, PFP_C
);
1251 state
->have_mask
= FALSE
;
1253 BEGIN_RING(chan
, fermi
, NVC0_3D_BIND_TIC(4), 1);
1254 OUT_RING (chan
, (1 << 1) | 0);
1256 BEGIN_RING(chan
, fermi
, NVC0_3D_SP_START_ID(5), 1);
1257 if (pdpict
->format
== PICT_a8
)
1258 OUT_RING (chan
, PFP_S_A8
);
1260 OUT_RING (chan
, PFP_S
);
1263 BEGIN_RING(chan
, fermi
, NVC0_3D_TSC_FLUSH
, 1);
1265 BEGIN_RING(chan
, fermi
, NVC0_3D_TIC_FLUSH
, 1);
1267 BEGIN_RING(chan
, fermi
, NVC0_3D_TEX_CACHE_CTL
, 1);
1271 pNv
->pspict
= pspict
;
1272 pNv
->pmpict
= pmpict
;
1273 pNv
->pdpict
= pdpict
;
1277 chan
->flush_notify
= NVC0EXAStateCompositeResubmit
;
1281 #define xFixedToFloat(v) \
1282 ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
1285 NVC0EXATransform(PictTransformPtr t
, int x
, int y
, float sx
, float sy
,
1286 float *x_ret
, float *y_ret
)
1291 v
.vector
[0] = IntToxFixed(x
);
1292 v
.vector
[1] = IntToxFixed(y
);
1293 v
.vector
[2] = xFixed1
;
1294 PictureTransformPoint(t
, &v
);
1295 *x_ret
= xFixedToFloat(v
.vector
[0]) / sx
;
1296 *y_ret
= xFixedToFloat(v
.vector
[1]) / sy
;
1298 *x_ret
= (float)x
/ sx
;
1299 *y_ret
= (float)y
/ sy
;
1304 NVC0EXAComposite(PixmapPtr pdpix
,
1305 int sx
, int sy
, int mx
, int my
,
1306 int dx
, int dy
, int w
, int h
)
1308 NVC0EXA_LOCALS(pdpix
);
1309 float sX0
, sX1
, sX2
, sY0
, sY1
, sY2
;
1311 WAIT_RING (chan
, 64);
1312 BEGIN_RING(chan
, fermi
, NVC0_3D_SCISSOR_HORIZ(0), 2);
1313 OUT_RING (chan
, ((dx
+ w
) << 16) | dx
);
1314 OUT_RING (chan
, ((dy
+ h
) << 16) | dy
);
1315 BEGIN_RING(chan
, fermi
, NVC0_3D_VERTEX_BEGIN_GL
, 1);
1316 OUT_RING (chan
, NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES
);
1318 NVC0EXATransform(state
->unit
[0].transform
, sx
, sy
+ (h
* 2),
1319 state
->unit
[0].width
, state
->unit
[0].height
,
1321 NVC0EXATransform(state
->unit
[0].transform
, sx
, sy
,
1322 state
->unit
[0].width
, state
->unit
[0].height
,
1324 NVC0EXATransform(state
->unit
[0].transform
, sx
+ (w
* 2), sy
,
1325 state
->unit
[0].width
, state
->unit
[0].height
,
1328 if (state
->have_mask
) {
1329 float mX0
, mX1
, mX2
, mY0
, mY1
, mY2
;
1331 NVC0EXATransform(state
->unit
[1].transform
, mx
, my
+ (h
* 2),
1332 state
->unit
[1].width
, state
->unit
[1].height
,
1334 NVC0EXATransform(state
->unit
[1].transform
, mx
, my
,
1335 state
->unit
[1].width
, state
->unit
[1].height
,
1337 NVC0EXATransform(state
->unit
[1].transform
, mx
+ (w
* 2), my
,
1338 state
->unit
[1].width
, state
->unit
[1].height
,
1341 VTX2s(pNv
, sX0
, sY0
, mX0
, mY0
, dx
, dy
+ (h
* 2));
1342 VTX2s(pNv
, sX1
, sY1
, mX1
, mY1
, dx
, dy
);
1343 VTX2s(pNv
, sX2
, sY2
, mX2
, mY2
, dx
+ (w
* 2), dy
);
1345 VTX1s(pNv
, sX0
, sY0
, dx
, dy
+ (h
* 2));
1346 VTX1s(pNv
, sX1
, sY1
, dx
, dy
);
1347 VTX1s(pNv
, sX2
, sY2
, dx
+ (w
* 2), dy
);
1350 BEGIN_RING(chan
, fermi
, NVC0_3D_VERTEX_END_GL
, 1);
1355 NVC0EXADoneComposite(PixmapPtr pdpix
)
1357 NVC0EXA_LOCALS(pdpix
);
1359 chan
->flush_notify
= NULL
;
1365 VOID
HIDDNouveauNVC0SetPattern(struct CardData
* carddata
, LONG clr0
, LONG clr1
,
1366 LONG pat0
, LONG pat1
)
1368 NVC0EXASetPattern(NULL
, clr0
, clr1
, pat0
, pat1
);
1371 /* NOTE: Assumes lock on bitmap is already made */
1372 /* NOTE: Assumes buffer is not mapped */
1373 BOOL
HIDDNouveauNVC0FillSolidRect(struct CardData
* carddata
,
1374 struct HIDDNouveauBitMapData
* bmdata
, LONG minX
, LONG minY
, LONG maxX
,
1375 LONG maxY
, ULONG drawmode
, ULONG color
)
1377 if (NVC0EXAPrepareSolid(bmdata
, drawmode
, ~0, color
))
1379 NVC0EXASolid(bmdata
, minX
, minY
, maxX
+ 1, maxY
+ 1);
1386 /* NOTE: Assumes lock on both bitmaps is already made */
1387 /* NOTE: Assumes both buffers are not mapped */
1388 BOOL
HIDDNouveauNVC0CopySameFormat(struct CardData
* carddata
,
1389 struct HIDDNouveauBitMapData
* srcdata
, struct HIDDNouveauBitMapData
* destdata
,
1390 LONG srcX
, LONG srcY
, LONG destX
, LONG destY
, LONG width
, LONG height
,
1393 if (NVC0EXAPrepareCopy(srcdata
, destdata
, 0, 0, drawmode
, ~0))
1395 NVC0EXACopy(destdata
, srcX
, srcY
, destX
, destY
, width
, height
);