randr12: Some misc changes.
[nouveau] / src / nv50_exa.c
1 #include "nv_include.h"
2
3 #define NV50_2D_NOP                                                   0x00000100
4 #define NV50_2D_UNK110                                                0x00000110
5 #define NV50_2D_DST_FORMAT                                            0x00000200
6 #define NV50_2D_SRC_FORMAT                                            0x00000230
7 #define NV50_2D_SRC_FORMAT_8BPP                                       0x000000f3
8 #define NV50_2D_SRC_FORMAT_15BPP                                      0x000000f8
9 #define NV50_2D_SRC_FORMAT_16BPP                                      0x000000e8
10 #define NV50_2D_SRC_FORMAT_24BPP                                      0x000000e6
11 #define NV50_2D_SRC_FORMAT_32BPP                                      0x000000cf
12 #define NV50_2D_CLIP_X                                                0x00000280
13 #define NV50_2D_SET_OPERATION                                         0x000002ac
14 #define NV50_2D_SET_OPERATION_ROP_AND                                 0x00000001
15 #define NV50_2D_SET_OPERATION_SRCCOPY                                 0x00000003
16 #define NV50_2D_RASTER_OP                                             0x000002a0
17 #define NV50_2D_PATTERN_FORMAT                                        0x000002e8
18 #define NV50_2D_PATTERN_COLOR_0                                       0x000002f0
19 #define NV50_2D_RECT_UNK580                                           0x00000580
20 #define NV50_2D_RECT_FORMAT                                           0x00000584
21 #define NV50_2D_RECT_X1                                               0x00000600
22 #define NV50_2D_BLIT_DST_X                                            0x000008b0
23
24 #define NV50EXA_LOCALS(p)                                              \
25         ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \
26         NVPtr pNv = NVPTR(pScrn);                                      \
27         (void)pNv
28
29 static Bool
30 NV50EXA2DSurfaceFormat(PixmapPtr pPix, uint32_t *fmt)
31 {
32         NV50EXA_LOCALS(pPix);
33
34         switch (pPix->drawable.depth) {
35         case 8 : *fmt = NV50_2D_SRC_FORMAT_8BPP; break;
36         case 15: *fmt = NV50_2D_SRC_FORMAT_15BPP; break;
37         case 16: *fmt = NV50_2D_SRC_FORMAT_16BPP; break;
38         case 24: *fmt = NV50_2D_SRC_FORMAT_24BPP; break;
39         case 32: *fmt = NV50_2D_SRC_FORMAT_32BPP; break;
40         default:
41                  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
42                             "Unknown surface format for bpp=%d\n",
43                             pPix->drawable.depth);
44                  return FALSE;
45         }
46
47         return TRUE;
48 }
49
50 static Bool
51 NV50EXAAcquireSurface2D(PixmapPtr pPix, int is_src)
52 {
53         NV50EXA_LOCALS(pPix);
54         int mthd = is_src ? NV50_2D_SRC_FORMAT : NV50_2D_DST_FORMAT;
55         uint32_t fmt;
56
57         if (!NV50EXA2DSurfaceFormat(pPix, &fmt))
58                 return FALSE;
59
60         NVDmaStart(pNv, Nv2D, mthd, 2);
61         NVDmaNext (pNv, fmt);
62         NVDmaNext (pNv, 1);
63
64         NVDmaStart(pNv, Nv2D, mthd + 0x14, 5);
65         NVDmaNext (pNv, (uint32_t)exaGetPixmapPitch(pPix));
66         NVDmaNext (pNv, pPix->drawable.width);
67         NVDmaNext (pNv, pPix->drawable.height);
68         NVDmaNext (pNv, 0);
69         NVDmaNext (pNv, NVAccelGetPixmapOffset(pPix));
70
71         if (is_src == 0) {
72                 NVDmaStart(pNv, Nv2D, NV50_2D_CLIP_X, 4);
73                 NVDmaNext (pNv, 0);
74                 NVDmaNext (pNv, 0);
75                 NVDmaNext (pNv, pPix->drawable.width);
76                 NVDmaNext (pNv, pPix->drawable.height);
77         }
78
79         return TRUE;
80 }
81
82 static Bool
83 NV50EXAAcquireSurfaces(PixmapPtr pdPix)
84 {
85         NV50EXA_LOCALS(pdPix);
86
87         return TRUE;
88 }
89
90 static void
91 NV50EXAReleaseSurfaces(PixmapPtr pdPix)
92 {
93         NV50EXA_LOCALS(pdPix);
94
95         NVDmaStart(pNv, Nv2D, NV50_2D_NOP, 1);
96         NVDmaNext (pNv, 0);
97         NVDmaKickoff(pNv);
98 }
99
100 static void
101 NV50EXASetPattern(PixmapPtr pdPix, int col0, int col1, int pat0, int pat1)
102 {
103         NV50EXA_LOCALS(pdPix);
104
105         NVDmaStart(pNv, Nv2D, NV50_2D_PATTERN_COLOR_0, 4);
106         NVDmaNext (pNv, col0);
107         NVDmaNext (pNv, col1);
108         NVDmaNext (pNv, pat0);
109         NVDmaNext (pNv, pat1);
110 }
111
112 extern const int NVCopyROP[16];
113 static void
114 NV50EXASetROP(PixmapPtr pdPix, int alu, Pixel planemask)
115 {
116         NV50EXA_LOCALS(pdPix);
117         int rop = NVCopyROP[alu];
118
119         NVDmaStart(pNv, Nv2D, NV50_2D_SET_OPERATION, 1);
120         if(alu == GXcopy && planemask == ~0) {
121                 NVDmaNext (pNv, NV50_2D_SET_OPERATION_SRCCOPY);
122                 return;
123         } else {
124                 NVDmaNext (pNv, NV50_2D_SET_OPERATION_ROP_AND);
125         }
126
127         NVDmaStart(pNv, Nv2D, NV50_2D_PATTERN_FORMAT, 1);
128         switch (pdPix->drawable.depth) {
129                 case  8: NVDmaNext(pNv, 3); break;
130                 case 15: NVDmaNext(pNv, 1); break;
131                 case 16: NVDmaNext(pNv, 0); break;
132                 case 24:
133                 case 32:
134                 default:
135                          NVDmaNext(pNv, 2);
136                          break;
137         }
138
139         if(planemask != ~0) {
140                 NV50EXASetPattern(pdPix, 0, planemask, ~0, ~0);
141                 rop = (rop & 0xf0) | 0x0a;
142         } else
143         if((pNv->currentRop & 0x0f) == 0x0a) {
144                 NV50EXASetPattern(pdPix, ~0, ~0, ~0, ~0);
145         }
146
147         if (pNv->currentRop != rop) {
148                 NVDmaStart(pNv, Nv2D, NV50_2D_RASTER_OP, 1);
149                 NVDmaNext (pNv, rop);
150                 pNv->currentRop = rop;
151         }
152 }
153
154 Bool
155 NV50EXAPrepareSolid(PixmapPtr pdPix, int alu, Pixel planemask, Pixel fg)
156 {
157         NV50EXA_LOCALS(pdPix);
158         uint32_t fmt;
159
160         if(pdPix->drawable.depth > 24)
161                 return FALSE;
162         if (!NV50EXA2DSurfaceFormat(pdPix, &fmt))
163                 return FALSE;
164
165         if (!NV50EXAAcquireSurface2D(pdPix, 0))
166                 return FALSE;
167         if (!NV50EXAAcquireSurfaces(pdPix))
168                 return FALSE;
169         NV50EXASetROP(pdPix, alu, planemask);
170
171         NVDmaStart(pNv, Nv2D, NV50_2D_RECT_UNK580, 3);
172         NVDmaNext (pNv, 4);
173         NVDmaNext (pNv, fmt);
174         NVDmaNext (pNv, fg);
175
176         return TRUE;
177 }
178
179 void
180 NV50EXASolid(PixmapPtr pdPix, int x1, int y1, int x2, int y2)
181 {
182         NV50EXA_LOCALS(pdPix);
183
184         NVDmaStart(pNv, Nv2D, NV50_2D_RECT_X1, 4);
185         NVDmaNext (pNv, x1);
186         NVDmaNext (pNv, y1);
187         NVDmaNext (pNv, x2);
188         NVDmaNext (pNv, y2);
189
190         if((x2 - x1) * (y2 - y1) >= 512)
191                 NVDmaKickoff(pNv);
192 }
193
194 void
195 NV50EXADoneSolid(PixmapPtr pdPix)
196 {
197         NV50EXA_LOCALS(pdPix);
198
199         NV50EXAReleaseSurfaces(pdPix);
200 }
201
202 Bool
203 NV50EXAPrepareCopy(PixmapPtr psPix, PixmapPtr pdPix, int dx, int dy,
204                    int alu, Pixel planemask)
205 {
206         NV50EXA_LOCALS(pdPix);
207
208         if (!NV50EXAAcquireSurface2D(psPix, 1))
209                 return FALSE;
210         if (!NV50EXAAcquireSurface2D(pdPix, 0))
211                 return FALSE;
212         if (!NV50EXAAcquireSurfaces(pdPix))
213                 return FALSE;
214         NV50EXASetROP(pdPix, alu, planemask);
215
216         return TRUE;
217 }
218
219 void
220 NV50EXACopy(PixmapPtr pdPix, int srcX , int srcY,
221                              int dstX , int dstY,
222                              int width, int height)
223 {
224         NV50EXA_LOCALS(pdPix);
225
226         NVDmaStart(pNv, Nv2D, NV50_2D_UNK110, 1);
227         NVDmaNext (pNv, 0);
228         NVDmaStart(pNv, Nv2D, NV50_2D_BLIT_DST_X, 12);
229         NVDmaNext (pNv, dstX);
230         NVDmaNext (pNv, dstY);
231         NVDmaNext (pNv, width);
232         NVDmaNext (pNv, height);
233         NVDmaNext (pNv, 0);
234         NVDmaNext (pNv, 1);
235         NVDmaNext (pNv, 0);
236         NVDmaNext (pNv, 1);
237         NVDmaNext (pNv, 0);
238         NVDmaNext (pNv, srcX);
239         NVDmaNext (pNv, 0);
240         NVDmaNext (pNv, srcY);
241
242         if(width * height >= 512)
243                 NVDmaKickoff(pNv);
244 }
245
246 void
247 NV50EXADoneCopy(PixmapPtr pdPix)
248 {
249         NV50EXA_LOCALS(pdPix);
250
251         NV50EXAReleaseSurfaces(pdPix);
252 }
253
254