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