1 #include "nv_include.h"
3 #define NV50EXA_LOCALS(p) \
4 ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \
5 NVPtr pNv = NVPTR(pScrn); \
9 NV50EXA2DSurfaceFormat(PixmapPtr pPix, uint32_t *fmt)
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;
20 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
21 "Unknown surface format for bpp=%d\n",
22 pPix->drawable.depth);
30 NV50EXAAcquireSurface2D(PixmapPtr pPix, int is_src)
33 int mthd = is_src ? NV50_2D_SRC_FORMAT : NV50_2D_DST_FORMAT;
34 uint32_t fmt, bo_flags;
36 if (!NV50EXA2DSurfaceFormat(pPix, &fmt))
39 bo_flags = NOUVEAU_BO_VRAM;
40 bo_flags |= is_src ? NOUVEAU_BO_RD : NOUVEAU_BO_WR;
42 BEGIN_RING(Nv2D, mthd, 2);
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);
54 BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4);
57 OUT_RING (pPix->drawable.width);
58 OUT_RING (pPix->drawable.height);
65 NV50EXAAcquireSurfaces(PixmapPtr pdPix)
67 NV50EXA_LOCALS(pdPix);
73 NV50EXAReleaseSurfaces(PixmapPtr pdPix)
75 NV50EXA_LOCALS(pdPix);
77 BEGIN_RING(Nv2D, NV50_2D_NOP, 1);
83 NV50EXASetPattern(PixmapPtr pdPix, int col0, int col1, int pat0, int pat1)
85 NV50EXA_LOCALS(pdPix);
87 BEGIN_RING(Nv2D, NV50_2D_PATTERN_COLOR(0), 4);
94 extern const int NVCopyROP[16];
96 NV50EXASetROP(PixmapPtr pdPix, int alu, Pixel planemask)
98 NV50EXA_LOCALS(pdPix);
99 int rop = NVCopyROP[alu];
101 BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1);
102 if(alu == GXcopy && planemask == ~0) {
103 OUT_RING (NV50_2D_OPERATION_SRCCOPY);
106 OUT_RING (NV50_2D_OPERATION_ROP_AND);
109 BEGIN_RING(Nv2D, NV50_2D_PATTERN_FORMAT, 2);
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;
122 if(planemask != ~0) {
123 NV50EXASetPattern(pdPix, 0, planemask, ~0, ~0);
124 rop = (rop & 0xf0) | 0x0a;
126 if((pNv->currentRop & 0x0f) == 0x0a) {
127 NV50EXASetPattern(pdPix, ~0, ~0, ~0, ~0);
130 if (pNv->currentRop != rop) {
131 BEGIN_RING(Nv2D, NV50_2D_ROP, 1);
133 pNv->currentRop = rop;
138 NV50EXAPrepareSolid(PixmapPtr pdPix, int alu, Pixel planemask, Pixel fg)
140 NV50EXA_LOCALS(pdPix);
143 if(pdPix->drawable.depth > 24)
145 if (!NV50EXA2DSurfaceFormat(pdPix, &fmt))
148 if (!NV50EXAAcquireSurface2D(pdPix, 0))
150 if (!NV50EXAAcquireSurfaces(pdPix))
152 NV50EXASetROP(pdPix, alu, planemask);
154 BEGIN_RING(Nv2D, 0x580, 3);
163 NV50EXASolid(PixmapPtr pdPix, int x1, int y1, int x2, int y2)
165 NV50EXA_LOCALS(pdPix);
167 BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4);
173 if((x2 - x1) * (y2 - y1) >= 512)
178 NV50EXADoneSolid(PixmapPtr pdPix)
180 NV50EXA_LOCALS(pdPix);
182 NV50EXAReleaseSurfaces(pdPix);
186 NV50EXAPrepareCopy(PixmapPtr psPix, PixmapPtr pdPix, int dx, int dy,
187 int alu, Pixel planemask)
189 NV50EXA_LOCALS(pdPix);
191 if (!NV50EXAAcquireSurface2D(psPix, 1))
193 if (!NV50EXAAcquireSurface2D(pdPix, 0))
195 if (!NV50EXAAcquireSurfaces(pdPix))
197 NV50EXASetROP(pdPix, alu, planemask);
203 NV50EXACopy(PixmapPtr pdPix, int srcX , int srcY,
205 int width, int height)
207 NV50EXA_LOCALS(pdPix);
209 BEGIN_RING(Nv2D, 0x0110, 1);
211 BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12);
225 if(width * height >= 512)
230 NV50EXADoneCopy(PixmapPtr pdPix)
232 NV50EXA_LOCALS(pdPix);
234 NV50EXAReleaseSurfaces(pdPix);
238 NV50EXAUploadSIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
239 PixmapPtr pdPix, int x, int y, int w, int h, int cpp)
241 NVPtr pNv = NVPTR(pScrn);
242 int line_dwords = (w * cpp + 3) / 4;
245 if (!NV50EXA2DSurfaceFormat(pdPix, &sifc_fmt))
247 if (!NV50EXAAcquireSurface2D(pdPix, 0))
250 BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1);
251 OUT_RING (NV50_2D_OPERATION_SRCCOPY);
252 BEGIN_RING(Nv2D, NV50_2D_SIFC_UNK0800, 2);
255 BEGIN_RING(Nv2D, NV50_2D_SIFC_WIDTH, 10);
256 OUT_RING ((line_dwords * 4) / cpp);
268 int count = line_dwords;
272 int size = count > 1792 ? 1792 : count;
274 BEGIN_RING(Nv2D, NV50_2D_SIFC_DATA | 0x40000000, size);