ffb_exa.c revision 89b0bd4c
1/* $NetBSD: ffb_exa.c,v 1.1 2015/08/11 03:57:36 macallan Exp $ */
2/*
3 * Copyright (c) 2015 Michael Lorenz
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 *    - Redistributions of source code must retain the above copyright
11 *      notice, this list of conditions and the following disclaimer.
12 *    - Redistributions in binary form must reproduce the above
13 *      copyright notice, this list of conditions and the following
14 *      disclaimer in the documentation and/or other materials provided
15 *      with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 */
31
32#include <sys/types.h>
33
34/* all driver need this */
35#include "xf86.h"
36#include "xf86_OSproc.h"
37#include "compiler.h"
38#include "exa.h"
39
40#include "ffb_fifo.h"
41#include "ffb_rcache.h"
42#include "ffb.h"
43#include "ffb_regs.h"
44
45extern void VISmoveImageRL(unsigned char *, unsigned char *, long, long, long, long);
46extern void VISmoveImageLR(unsigned char *, unsigned char *, long, long, long, long);
47
48/*#define FFB_DEBUG*/
49
50#ifdef FFB_DEBUG
51#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__);
52#define DPRINTF xf86Msg
53#else
54#define ENTER
55#define DPRINTF while (0) xf86Msg
56#endif
57
58static void
59FFBWaitMarker(ScreenPtr pScreen, int Marker)
60{
61	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
62	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
63	ffb_fbcPtr ffb = pFfb->regs;
64
65	FFBWait(pFfb, ffb);
66}
67
68static Bool
69FFBPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
70		int xdir, int ydir, int alu, Pixel planemask)
71{
72	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
73	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
74	ffb_fbcPtr ffb = pFfb->regs;
75
76	ENTER;
77	pFfb->srcpitch = exaGetPixmapPitch(pSrcPixmap);
78	pFfb->srcoff = exaGetPixmapOffset(pSrcPixmap);
79	pFfb->xdir = xdir;
80	pFfb->ydir = ydir;
81	pFfb->rop = alu;
82	pFfb->planemask = planemask;
83	return TRUE;
84}
85
86static void
87FFBCopy(PixmapPtr pDstPixmap,
88         int srcX, int srcY, int dstX, int dstY, int w, int h)
89{
90	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
91	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
92	ffb_fbcPtr ffb = pFfb->regs;
93	unsigned char *src, *dst, *sfb32;
94	int psz_shift = 2;
95	int sdkind;
96
97	ENTER;
98	if ((srcX == dstX) && (srcY != dstY) && (pFfb->rop == GXcopy)) {
99		/* we can use the vscroll command */
100		FFB_ATTR_VSCROLL_XAA(pFfb, pFfb->planemask);
101		FFBFifo(pFfb, 7);
102		ffb->drawop = FFB_DRAWOP_VSCROLL;
103		FFB_WRITE64(&ffb->by, srcY, srcX);
104                       FFB_WRITE64_2(&ffb->dy, dstY, dstX);
105                       FFB_WRITE64_3(&ffb->bh, h, w);
106		exaMarkSync(pDstPixmap->drawable.pScreen);
107		return;
108	}
109	FFB_ATTR_SFB_VAR_XAA(pFfb, pFfb->planemask, pFfb->rop);
110	FFBWait(pFfb, ffb);
111	sfb32 = (unsigned char *) pFfb->sfb32;
112	src = sfb32 + (srcY * (2048 << psz_shift)) + (srcX << psz_shift);
113	dst = sfb32 + (dstY * (2048 << psz_shift)) + (dstX << psz_shift);
114	sdkind = (2048 << psz_shift);
115
116	if (pFfb->ydir < 0) {
117		src += ((h - 1) * (2048 << psz_shift));
118		dst += ((h - 1) * (2048 << psz_shift));
119		sdkind = -sdkind;
120	}
121	w <<= psz_shift;
122	if (pFfb->xdir < 0)
123		VISmoveImageRL(src, dst, w, h, sdkind, sdkind);
124	else
125		VISmoveImageLR(src, dst, w, h, sdkind, sdkind);
126}
127
128static void
129FFBDoneCopy(PixmapPtr pDstPixmap)
130{
131}
132
133static Bool
134FFBPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
135{
136	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
137	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
138	ffb_fbcPtr ffb = pFfb->regs;
139	unsigned int ppc, ppc_mask, fbc;
140
141	ENTER;
142	FFBWait(pFfb, ffb);
143	pFfb->planemask = planemask;
144	pFfb->rop = alu;
145
146	fbc = pFfb->fbc;
147	if (pFfb->ffb_res == ffb_res_high)
148		fbc |= FFB_FBC_WB_B;
149	ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
150	ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
151
152	FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
153                    (FFB_ROP_EDIT_BIT | alu) | (FFB_ROP_NEW << 8),
154                    FFB_DRAWOP_RECTANGLE, fg, fbc, pFfb->wid);
155
156	return TRUE;
157}
158
159static void
160FFBSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
161{
162	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
163	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
164	ffb_fbcPtr ffb = pFfb->regs;
165
166	ENTER;
167	FFBFifo(pFfb, 4);
168	FFB_WRITE64(&ffb->by, y1, x1);
169	FFB_WRITE64_2(&ffb->bh, y2 - y1, x2 - x1);
170	exaMarkSync(pPixmap->drawable.pScreen);
171}
172
173static Bool
174FFBUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
175    char *src, int src_pitch)
176{
177	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
178	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
179	unsigned char *dst, *sfb32;
180	int psz_shift = 2;
181	ffb_fbcPtr ffb = pFfb->regs;
182
183	ENTER;
184	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
185	FFBWait(pFfb, ffb);
186
187	sfb32 = (unsigned char *) pFfb->sfb32;
188	dst = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift);
189	VISmoveImageLR(src, dst, w << psz_shift, h,
190		src_pitch, (2048 << psz_shift));
191	return TRUE;
192}
193
194static Bool
195FFBDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
196    char *dst, int dst_pitch)
197{
198	ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
199	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
200	unsigned char *src, *sfb32;
201	int psz_shift = 2;
202	ffb_fbcPtr ffb = pFfb->regs;
203
204	ENTER;
205	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
206	FFBWait(pFfb, ffb);
207
208	sfb32 = (unsigned char *) pFfb->sfb32;
209	src = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift);
210	VISmoveImageLR(src, dst, w << psz_shift, h,
211		(2048 << psz_shift), dst_pitch);
212	return TRUE;
213}
214
215#if 0
216
217Bool
218FFBCheckComposite(int op, PicturePtr pSrcPicture,
219                           PicturePtr pMaskPicture,
220                           PicturePtr pDstPicture)
221{
222	return FALSE;
223}
224
225Bool
226FFBPrepareComposite(int op, PicturePtr pSrcPicture,
227                             PicturePtr pMaskPicture,
228                             PicturePtr pDstPicture,
229                             PixmapPtr  pSrc,
230                             PixmapPtr  pMask,
231                             PixmapPtr  pDst)
232{
233	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
234	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
235
236	ENTER;
237	return FALSE;
238}
239
240void
241FFBComposite(PixmapPtr pDst, int srcX, int srcY,
242                              int maskX, int maskY,
243                              int dstX, int dstY,
244                              int width, int height)
245{
246	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
247	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
248	exaMarkSync(pDst->drawable.pScreen);
249}
250
251#endif
252
253static Bool
254FFBPrepareAccess(PixmapPtr pPix, int index)
255{
256	ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
257	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
258	ffb_fbcPtr ffb = pFfb->regs;
259
260	ENTER;
261	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
262	FFBWait(pFfb, ffb);
263
264	return TRUE;
265}
266
267static void
268FFBFinishAccess(PixmapPtr pPix, int index)
269{
270}
271
272Bool
273FFBInitEXA(ScreenPtr pScreen)
274{
275	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
276	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
277	ffb_fbcPtr ffb = pFfb->regs;
278	ExaDriverPtr pExa;
279
280	pFfb->fbc = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
281			 FFB_FBC_WE_FORCEON |
282			 FFB_FBC_SB_BOTH |
283			 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
284			 FFB_FBC_RGBE_MASK |
285			 FFB_FBC_XE_ON);
286	pFfb->wid = FFBWidAlloc(pFfb, TrueColor, 0, TRUE);
287	if (pFfb->wid == (unsigned int) -1)
288		return FALSE;
289
290	pFfb->ppc_cache = (FFB_PPC_FW_DISABLE |
291			   FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST |
292			   FFB_PPC_XS_WID | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST |
293			   FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE);
294	pFfb->wid_cache = pFfb->wid;
295	pFfb->pmask_cache = ~0;
296	pFfb->rop_cache = (FFB_ROP_NEW | (FFB_ROP_NEW << 8));
297	pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
298	pFfb->fg_cache = pFfb->bg_cache = 0;
299	pFfb->fontw_cache = 32;
300	pFfb->fontinc_cache = (1 << 16) | 0;
301	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
302			   FFB_FBC_WE_FORCEON |
303			   FFB_FBC_SB_BOTH |
304			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
305			   FFB_FBC_RGBE_OFF |
306			   FFB_FBC_XE_ON);
307
308	/* We will now clear the screen: we'll draw a rectangle covering all the
309	 * viewscreen, using a 'blackness' ROP.
310	 */
311	FFBFifo(pFfb, 22);
312	ffb->fbc = pFfb->fbc_cache;
313	ffb->ppc = pFfb->ppc_cache;
314	ffb->wid = pFfb->wid_cache;
315	ffb->xpmask = 0xff;
316	ffb->pmask = pFfb->pmask_cache;
317	ffb->rop = pFfb->rop_cache;
318	ffb->drawop = pFfb->drawop_cache;
319	ffb->fg = pFfb->fg_cache;
320	ffb->bg = pFfb->bg_cache;
321	ffb->fontw = pFfb->fontw_cache;
322	ffb->fontinc = pFfb->fontinc_cache;
323	ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
324	ffb->cmp = 0x80808080;
325	ffb->matchab = 0x80808080;
326	ffb->magnab = 0x80808080;
327	ffb->blendc = (FFB_BLENDC_FORCE_ONE |
328		       FFB_BLENDC_DF_ONE_M_A |
329		       FFB_BLENDC_SF_A);
330	ffb->blendc1 = 0;
331	ffb->blendc2 = 0;
332	FFB_WRITE64(&ffb->by, 0, 0);
333	FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width);
334	FFBWait(pFfb, ffb);
335
336	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
337	FFBWait(pFfb, ffb);
338
339	pExa = exaDriverAlloc();
340	if (!pExa)
341		return FALSE;
342
343	pFfb->pExa = pExa;
344
345	pExa->exa_major = EXA_VERSION_MAJOR;
346	pExa->exa_minor = EXA_VERSION_MINOR;
347
348
349	pExa->memoryBase = (char *)pFfb->sfb32;
350	/*
351	 * we don't have usable off-screen memory but EXA craps out if we don't
352	 * pretend that we do, so register a ridiculously small amount and
353	 * cross fingers
354	 */
355	pExa->memorySize = 8192 * pFfb->psdp->height + 4;
356	pExa->offScreenBase = pExa->memorySize - 4;
357
358	/* we want to use 64bit aligned accesses */
359	pExa->pixmapOffsetAlign = 8;
360	pExa->pixmapPitchAlign = 8;
361
362	pExa->flags = EXA_OFFSCREEN_PIXMAPS |
363		      /*EXA_SUPPORTS_OFFSCREEN_OVERLAPS |*/
364		      EXA_MIXED_PIXMAPS;
365
366	pExa->maxX = 2048;
367	pExa->maxY = 2048;
368
369	pExa->WaitMarker = FFBWaitMarker;
370
371	pExa->PrepareSolid = FFBPrepareSolid;
372	pExa->Solid = FFBSolid;
373	pExa->DoneSolid = FFBDoneCopy;
374	pExa->PrepareCopy = FFBPrepareCopy;
375	pExa->Copy = FFBCopy;
376	pExa->DoneCopy = FFBDoneCopy;
377	pExa->UploadToScreen = FFBUploadToScreen;
378	pExa->DownloadFromScreen = FFBDownloadFromScreen;
379	pExa->PrepareAccess = FFBPrepareAccess;
380	pExa->FinishAccess = FFBFinishAccess;
381#if 0
382	pExa->CheckComposite = CG14CheckComposite;
383	pExa->PrepareComposite = CG14PrepareComposite;
384	pExa->Composite = CG14Composite;
385	pExa->DoneComposite = CG14DoneCopy;
386#endif
387
388	return exaDriverInit(pScreen, pExa);
389}
390