~ubuntu-branches/ubuntu/karmic/xserver-xorg-video-nouveau/karmic

« back to all changes in this revision

Viewing changes to src/nv50_exa.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2008-07-06 20:26:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080706202653-e99oiii765j3a0qn
Tags: upstream-0.0.10~git+20080706+b1f3169
ImportĀ upstreamĀ versionĀ 0.0.10~git+20080706+b1f3169

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2007 NVIDIA, Corporation
 
3
 * Copyright 2008 Ben Skeggs
 
4
 *
 
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:
 
11
 *
 
12
 * The above copyright notice and this permission notice shall be included in
 
13
 * all copies or substantial portions of the Software.
 
14
 *
 
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
 
21
 * SOFTWARE.
 
22
 */
 
23
 
 
24
#include "nv_include.h"
 
25
 
 
26
#define NV50EXA_LOCALS(p)                                              \
 
27
        ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \
 
28
        NVPtr pNv = NVPTR(pScrn);                                      \
 
29
        (void)pNv
 
30
 
 
31
static Bool
 
32
NV50EXA2DSurfaceFormat(PixmapPtr pPix, uint32_t *fmt)
 
33
{
 
34
        NV50EXA_LOCALS(pPix);
 
35
 
 
36
        switch (pPix->drawable.depth) {
 
37
        case 8 : *fmt = NV50_2D_SRC_FORMAT_8BPP; break;
 
38
        case 15: *fmt = NV50_2D_SRC_FORMAT_15BPP; break;
 
39
        case 16: *fmt = NV50_2D_SRC_FORMAT_16BPP; break;
 
40
        case 24: *fmt = NV50_2D_SRC_FORMAT_24BPP; break;
 
41
        case 32: *fmt = NV50_2D_SRC_FORMAT_32BPP; break;
 
42
        default:
 
43
                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
44
                            "Unknown surface format for bpp=%d\n",
 
45
                            pPix->drawable.depth);
 
46
                 return FALSE;
 
47
        }
 
48
 
 
49
        return TRUE;
 
50
}
 
51
 
 
52
static Bool
 
53
NV50EXAAcquireSurface2D(PixmapPtr pPix, int is_src)
 
54
{
 
55
        NV50EXA_LOCALS(pPix);
 
56
        int mthd = is_src ? NV50_2D_SRC_FORMAT : NV50_2D_DST_FORMAT;
 
57
        uint32_t fmt, bo_flags;
 
58
 
 
59
        if (!NV50EXA2DSurfaceFormat(pPix, &fmt))
 
60
                return FALSE;
 
61
 
 
62
        bo_flags  = NOUVEAU_BO_VRAM;
 
63
        bo_flags |= is_src ? NOUVEAU_BO_RD : NOUVEAU_BO_WR;
 
64
 
 
65
        BEGIN_RING(Nv2D, mthd, 2);
 
66
        OUT_RING  (fmt);
 
67
        OUT_RING  (1);
 
68
 
 
69
        BEGIN_RING(Nv2D, mthd + 0x14, 5);
 
70
        OUT_RING  ((uint32_t)exaGetPixmapPitch(pPix));
 
71
        OUT_RING  (pPix->drawable.width);
 
72
        OUT_RING  (pPix->drawable.height);
 
73
        OUT_PIXMAPh(pPix, 0, bo_flags);
 
74
        OUT_PIXMAPl(pPix, 0, bo_flags);
 
75
 
 
76
        if (is_src == 0) {
 
77
                BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4);
 
78
                OUT_RING  (0);
 
79
                OUT_RING  (0);
 
80
                OUT_RING  (pPix->drawable.width);
 
81
                OUT_RING  (pPix->drawable.height);
 
82
        }
 
83
 
 
84
        return TRUE;
 
85
}
 
86
 
 
87
static Bool
 
88
NV50EXAAcquireSurfaces(PixmapPtr pdPix)
 
89
{
 
90
        NV50EXA_LOCALS(pdPix);
 
91
 
 
92
        return TRUE;
 
93
}
 
94
 
 
95
static void
 
96
NV50EXAReleaseSurfaces(PixmapPtr pdPix)
 
97
{
 
98
        NV50EXA_LOCALS(pdPix);
 
99
 
 
100
        BEGIN_RING(Nv2D, NV50_2D_NOP, 1);
 
101
        OUT_RING  (0);
 
102
        FIRE_RING();
 
103
}
 
104
 
 
105
static void
 
106
NV50EXASetPattern(PixmapPtr pdPix, int col0, int col1, int pat0, int pat1)
 
107
{
 
108
        NV50EXA_LOCALS(pdPix);
 
109
 
 
110
        BEGIN_RING(Nv2D, NV50_2D_PATTERN_COLOR(0), 4);
 
111
        OUT_RING  (col0);
 
112
        OUT_RING  (col1);
 
113
        OUT_RING  (pat0);
 
114
        OUT_RING  (pat1);
 
115
}
 
116
 
 
117
extern const int NVCopyROP[16];
 
118
static void
 
119
NV50EXASetROP(PixmapPtr pdPix, int alu, Pixel planemask)
 
120
{
 
121
        NV50EXA_LOCALS(pdPix);
 
122
        int rop = NVCopyROP[alu];
 
123
 
 
124
        BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1);
 
125
        if(alu == GXcopy && planemask == ~0) {
 
126
                OUT_RING  (NV50_2D_OPERATION_SRCCOPY);
 
127
                return;
 
128
        } else {
 
129
                OUT_RING  (NV50_2D_OPERATION_ROP_AND);
 
130
        }
 
131
 
 
132
        BEGIN_RING(Nv2D, NV50_2D_PATTERN_FORMAT, 2);
 
133
        switch (pdPix->drawable.depth) {
 
134
                case  8: OUT_RING  (3); break;
 
135
                case 15: OUT_RING  (1); break;
 
136
                case 16: OUT_RING  (0); break;
 
137
                case 24:
 
138
                case 32:
 
139
                default:
 
140
                         OUT_RING  (2);
 
141
                         break;
 
142
        }
 
143
        OUT_RING(1);
 
144
 
 
145
        if(planemask != ~0) {
 
146
                NV50EXASetPattern(pdPix, 0, planemask, ~0, ~0);
 
147
                rop = (rop & 0xf0) | 0x0a;
 
148
        } else
 
149
        if((pNv->currentRop & 0x0f) == 0x0a) {
 
150
                NV50EXASetPattern(pdPix, ~0, ~0, ~0, ~0);
 
151
        }
 
152
 
 
153
        if (pNv->currentRop != rop) {
 
154
                BEGIN_RING(Nv2D, NV50_2D_ROP, 1);
 
155
                OUT_RING  (rop);
 
156
                pNv->currentRop = rop;
 
157
        }
 
158
}
 
159
 
 
160
Bool
 
161
NV50EXAPrepareSolid(PixmapPtr pdPix, int alu, Pixel planemask, Pixel fg)
 
162
{
 
163
        NV50EXA_LOCALS(pdPix);
 
164
        uint32_t fmt;
 
165
 
 
166
        if(pdPix->drawable.depth > 24)
 
167
                return FALSE;
 
168
        if (!NV50EXA2DSurfaceFormat(pdPix, &fmt))
 
169
                return FALSE;
 
170
 
 
171
        if (!NV50EXAAcquireSurface2D(pdPix, 0))
 
172
                return FALSE;
 
173
        if (!NV50EXAAcquireSurfaces(pdPix))
 
174
                return FALSE;
 
175
        NV50EXASetROP(pdPix, alu, planemask);
 
176
 
 
177
        BEGIN_RING(Nv2D, 0x580, 3);
 
178
        OUT_RING  (4);
 
179
        OUT_RING  (fmt);
 
180
        OUT_RING  (fg);
 
181
 
 
182
        return TRUE;
 
183
}
 
184
 
 
185
void
 
186
NV50EXASolid(PixmapPtr pdPix, int x1, int y1, int x2, int y2)
 
187
{
 
188
        NV50EXA_LOCALS(pdPix);
 
189
 
 
190
        BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4);
 
191
        OUT_RING  (x1);
 
192
        OUT_RING  (y1);
 
193
        OUT_RING  (x2);
 
194
        OUT_RING  (y2);
 
195
 
 
196
        if((x2 - x1) * (y2 - y1) >= 512)
 
197
                FIRE_RING();
 
198
}
 
199
 
 
200
void
 
201
NV50EXADoneSolid(PixmapPtr pdPix)
 
202
{
 
203
        NV50EXA_LOCALS(pdPix);
 
204
 
 
205
        NV50EXAReleaseSurfaces(pdPix);
 
206
}
 
207
 
 
208
Bool
 
209
NV50EXAPrepareCopy(PixmapPtr psPix, PixmapPtr pdPix, int dx, int dy,
 
210
                   int alu, Pixel planemask)
 
211
{
 
212
        NV50EXA_LOCALS(pdPix);
 
213
 
 
214
        if (!NV50EXAAcquireSurface2D(psPix, 1))
 
215
                return FALSE;
 
216
        if (!NV50EXAAcquireSurface2D(pdPix, 0))
 
217
                return FALSE;
 
218
        if (!NV50EXAAcquireSurfaces(pdPix))
 
219
                return FALSE;
 
220
        NV50EXASetROP(pdPix, alu, planemask);
 
221
 
 
222
        return TRUE;
 
223
}
 
224
 
 
225
void
 
226
NV50EXACopy(PixmapPtr pdPix, int srcX , int srcY,
 
227
                             int dstX , int dstY,
 
228
                             int width, int height)
 
229
{
 
230
        NV50EXA_LOCALS(pdPix);
 
231
 
 
232
        BEGIN_RING(Nv2D, 0x0110, 1);
 
233
        OUT_RING  (0);
 
234
        BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12);
 
235
        OUT_RING  (dstX);
 
236
        OUT_RING  (dstY);
 
237
        OUT_RING  (width);
 
238
        OUT_RING  (height);
 
239
        OUT_RING  (0);
 
240
        OUT_RING  (1);
 
241
        OUT_RING  (0);
 
242
        OUT_RING  (1);
 
243
        OUT_RING  (0);
 
244
        OUT_RING  (srcX);
 
245
        OUT_RING  (0);
 
246
        OUT_RING  (srcY);
 
247
 
 
248
        if(width * height >= 512)
 
249
                FIRE_RING();
 
250
}
 
251
 
 
252
void
 
253
NV50EXADoneCopy(PixmapPtr pdPix)
 
254
{
 
255
        NV50EXA_LOCALS(pdPix);
 
256
 
 
257
        NV50EXAReleaseSurfaces(pdPix);
 
258
}
 
259
 
 
260
Bool
 
261
NV50EXAUploadSIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
 
262
                  PixmapPtr pdPix, int x, int y, int w, int h, int cpp)
 
263
{
 
264
        NVPtr pNv = NVPTR(pScrn);
 
265
        int line_dwords = (w * cpp + 3) / 4;
 
266
        uint32_t sifc_fmt;
 
267
 
 
268
        if (!NV50EXA2DSurfaceFormat(pdPix, &sifc_fmt))
 
269
                return FALSE;
 
270
        if (!NV50EXAAcquireSurface2D(pdPix, 0))
 
271
                return FALSE;
 
272
 
 
273
        BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1);
 
274
        OUT_RING (NV50_2D_OPERATION_SRCCOPY);
 
275
        BEGIN_RING(Nv2D, NV50_2D_SIFC_UNK0800, 2);
 
276
        OUT_RING (0);
 
277
        OUT_RING (sifc_fmt);
 
278
        BEGIN_RING(Nv2D, NV50_2D_SIFC_WIDTH, 10);
 
279
        OUT_RING ((line_dwords * 4) / cpp);
 
280
        OUT_RING (h);
 
281
        OUT_RING (0);
 
282
        OUT_RING (1);
 
283
        OUT_RING (0);
 
284
        OUT_RING (1);
 
285
        OUT_RING (0);
 
286
        OUT_RING (x);
 
287
        OUT_RING (0);
 
288
        OUT_RING (y);
 
289
 
 
290
        while (h--) {
 
291
                int count = line_dwords;
 
292
                const char *p = src;
 
293
 
 
294
                while(count) {
 
295
                        int size = count > 1792 ? 1792 : count;
 
296
 
 
297
                        BEGIN_RING(Nv2D, NV50_2D_SIFC_DATA | 0x40000000, size);
 
298
                        OUT_RINGp (p, size);
 
299
 
 
300
                        p += size * cpp;
 
301
                        count -= size;
 
302
                }
 
303
 
 
304
                src += src_pitch;
 
305
        }
 
306
 
 
307
        return TRUE;
 
308
}
 
309