1
2/**************************************************************************
3
4Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5All Rights Reserved.
6
7Permission is hereby granted, free of charge, to any person obtaining a
8copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sub license, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice (including the
16next paragraph) shall be included in all copies or substantial portions
17of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27**************************************************************************/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33/*
34 * Authors:
35 *   Keith Whitwell <keith@tungstengraphics.com>
36 *
37 */
38
39#include "xorg-server.h"
40#include "xf86.h"
41#include "xaarop.h"
42#include "i810.h"
43
44static void
45I810SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
46			       int fg, int bg, int rop,
47			       unsigned int planemask)
48{
49   I810Ptr pI810 = I810PTR(pScrn);
50
51   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
52      ErrorF("I810SetupFor8x8PatternColorExpand\n");
53
54   /* FULL_MONO_PAT_BLT, p176 */
55   pI810->BR[0] = (BR00_BITBLT_CLIENT | BR00_OP_MONO_PAT_BLT | 0x9);
56   pI810->BR[18] = bg;
57   pI810->BR[19] = fg;
58   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
59   pI810->BR[13] |= I810PatternROP[rop] << 16;
60   if (bg == -1)
61      pI810->BR[13] |= BR13_MONO_PATN_TRANS;
62}
63
64static void
65I810SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
66				     int x, int y, int w, int h)
67{
68   I810Ptr pI810 = I810PTR(pScrn);
69   int addr =
70	 pI810->bufferOffset + (y * pScrn->displayWidth + x) * pI810->cpp;
71
72   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
73      ErrorF("I810Subsequent8x8PatternColorExpand\n");
74
75   {
76      BEGIN_LP_RING(12);
77      OUT_RING(pI810->BR[0] | ((y << 5) & BR00_PAT_VERT_ALIGN));
78      OUT_RING(pI810->BR[13]);
79      OUT_RING((h << 16) | (w * pI810->cpp));
80      OUT_RING(addr);
81      OUT_RING(pI810->BR[13] & 0xFFFF);	/* src pitch */
82      OUT_RING(addr);			/* src addr */
83      OUT_RING(0);			/* transparency color */
84      OUT_RING(pI810->BR[18]);		/* bg */
85      OUT_RING(pI810->BR[19]);		/* fg */
86      OUT_RING(pattx);			/* pattern data */
87      OUT_RING(patty);
88      OUT_RING(0);
89      ADVANCE_LP_RING();
90   }
91}
92
93static void
94I810GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
95{
96   I810Ptr pI810 = I810PTR(pScrn);
97   XAAInfoRecPtr infoPtr = pI810->AccelInfoRec;
98
99   if (pI810->nextColorExpandBuf == pI810->NumScanlineColorExpandBuffers)
100      I810Sync(pScrn);
101
102   infoPtr->ScanlineColorExpandBuffers[0] =
103	 pI810->ScanlineColorExpandBuffers[pI810->nextColorExpandBuf];
104
105   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
106      ErrorF("using color expand buffer %d\n", pI810->nextColorExpandBuf);
107
108   pI810->nextColorExpandBuf++;
109}
110
111static void
112I810SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
113					       int fg, int bg, int rop,
114					       unsigned int planemask)
115{
116   I810Ptr pI810 = I810PTR(pScrn);
117
118   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
119      ErrorF("I810SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
120	     fg, bg, rop, planemask);
121
122   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
123   pI810->BR[13] |= I810CopyROP[rop] << 16;
124   pI810->BR[13] |= (1 << 27);
125   if (bg == -1)
126      pI810->BR[13] |= BR13_MONO_TRANSPCY;
127
128   pI810->BR[18] = bg;
129   pI810->BR[19] = fg;
130
131   I810GetNextScanlineColorExpandBuffer(pScrn);
132}
133
134static void
135I810SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
136						 int x, int y,
137						 int w, int h, int skipleft)
138{
139   I810Ptr pI810 = I810PTR(pScrn);
140
141   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
142      ErrorF("I810SubsequentScanlineCPUToScreenColorExpandFill "
143	     "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
144
145   pI810->BR[0] = BR00_BITBLT_CLIENT | BR00_OP_MONO_SRC_COPY_BLT | 0x06;
146   pI810->BR[9] = (pI810->bufferOffset +
147		   (y * pScrn->displayWidth + x) * pI810->cpp);
148   pI810->BR[14] = ((1 << 16) | (w * pI810->cpp));
149   pI810->BR[11] = ((w + 31) / 32) - 1;
150}
151
152static void
153I810SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
154{
155   I810Ptr pI810 = I810PTR(pScrn);
156
157   pI810->BR[12] = (pI810->AccelInfoRec->ScanlineColorExpandBuffers[0] -
158		    pI810->FbBase);
159
160   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
161      ErrorF("I810SubsequentColorExpandScanline %d (addr %x)\n",
162	     bufno, pI810->BR[12]);
163
164   {
165      BEGIN_LP_RING(8);
166      OUT_RING(pI810->BR[0]);
167      OUT_RING(pI810->BR[13]);
168      OUT_RING(pI810->BR[14]);
169      OUT_RING(pI810->BR[9]);
170      OUT_RING(pI810->BR[11]);
171      OUT_RING(pI810->BR[12]);		/* srcaddr */
172      OUT_RING(pI810->BR[18]);
173      OUT_RING(pI810->BR[19]);
174      ADVANCE_LP_RING();
175   }
176
177   /* Advance to next scanline.
178    */
179   pI810->BR[9] += pScrn->displayWidth * pI810->cpp;
180   I810GetNextScanlineColorExpandBuffer(pScrn);
181}
182
183/* Emit on gaining VT?
184 */
185#if 0
186static void
187I810EmitInvarientState(ScrnInfoPtr pScrn)
188{
189   I810Ptr pI810 = I810PTR(pScrn);
190
191   BEGIN_LP_RING(10);
192
193   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
194   OUT_RING(GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0);
195   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
196   OUT_RING(0);
197
198   OUT_RING(GFX_OP_COLOR_CHROMA_KEY);
199   OUT_RING(CC1_UPDATE_KILL_WRITE |
200	    CC1_DISABLE_KILL_WRITE |
201	    CC1_UPDATE_COLOR_IDX |
202	    CC1_UPDATE_CHROMA_LOW | CC1_UPDATE_CHROMA_HI | 0);
203   OUT_RING(0);
204   OUT_RING(0);
205
206/*     OUT_RING( CMD_OP_Z_BUFFER_INFO ); */
207/*     OUT_RING( pI810->DepthBuffer.Start | pI810->auxPitchBits); */
208
209   ADVANCE_LP_RING();
210}
211#endif
212
213/* The following function sets up the supported acceleration. Call it
214 * from the FbInit() function in the SVGA driver, or before ScreenInit
215 * in a monolithic server.
216 */
217Bool
218I810AccelInit(ScreenPtr pScreen)
219{
220   XAAInfoRecPtr infoPtr;
221   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
222   I810Ptr pI810 = I810PTR(pScrn);
223
224   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
225      ErrorF("I810AccelInit\n");
226
227   pI810->AccelInfoRec = infoPtr = XAACreateInfoRec();
228   if (!infoPtr)
229      return FALSE;
230
231   pI810->bufferOffset = 0;
232   infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
233   infoPtr->Flags |= PIXMAP_CACHE;
234
235   /* Sync
236    */
237   infoPtr->Sync = I810Sync;
238
239   /* Solid filled rectangles
240    */
241   {
242      infoPtr->SolidFillFlags = NO_PLANEMASK;
243      infoPtr->SetupForSolidFill = I810SetupForSolidFill;
244      infoPtr->SubsequentSolidFillRect = I810SubsequentSolidFillRect;
245   }
246
247   /* Screen to screen copy
248    *   - the transparency op hangs the blit engine, disable for now.
249    */
250   {
251      infoPtr->ScreenToScreenCopyFlags = (0
252					  | NO_PLANEMASK
253					  | NO_TRANSPARENCY | 0);
254
255      infoPtr->SetupForScreenToScreenCopy = I810SetupForScreenToScreenCopy;
256      infoPtr->SubsequentScreenToScreenCopy =
257	    I810SubsequentScreenToScreenCopy;
258   }
259
260   /* 8x8 pattern fills
261    */
262   {
263      infoPtr->SetupForMono8x8PatternFill = I810SetupForMono8x8PatternFill;
264      infoPtr->SubsequentMono8x8PatternFillRect =
265	    I810SubsequentMono8x8PatternFillRect;
266
267      infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
268					  HARDWARE_PATTERN_SCREEN_ORIGIN |
269					  BIT_ORDER_IN_BYTE_MSBFIRST |
270					  NO_PLANEMASK | 0);
271   }
272
273   /* 8x8 color fills - not considered useful for XAA.
274    */
275
276   /* Scanline color expansion - Use the same scheme as the 3.3 driver.
277    *
278    */
279   if (pI810->Scratch.Size != 0) {
280      int i;
281      int width = ALIGN(pScrn->displayWidth, 32) / 8;
282      int nr_buffers = pI810->Scratch.Size / width;
283      unsigned char *ptr = pI810->FbBase + pI810->Scratch.Start;
284
285      pI810->NumScanlineColorExpandBuffers = nr_buffers;
286      pI810->ScanlineColorExpandBuffers = (unsigned char **)
287	    xnfcalloc(nr_buffers, sizeof(unsigned char *));
288
289      for (i = 0; i < nr_buffers; i++, ptr += width)
290	 pI810->ScanlineColorExpandBuffers[i] = ptr;
291
292      infoPtr->ScanlineCPUToScreenColorExpandFillFlags = (NO_PLANEMASK |
293							  ROP_NEEDS_SOURCE |
294							  BIT_ORDER_IN_BYTE_MSBFIRST
295							  | 0);
296
297      infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
298	    xnfcalloc(1, sizeof(unsigned char *));
299      infoPtr->NumScanlineColorExpandBuffers = 1;
300
301      infoPtr->ScanlineColorExpandBuffers[0] =
302	    pI810->ScanlineColorExpandBuffers[0];
303      pI810->nextColorExpandBuf = 0;
304
305      infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
306	    I810SetupForScanlineCPUToScreenColorExpandFill;
307
308      infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
309	    I810SubsequentScanlineCPUToScreenColorExpandFill;
310
311      infoPtr->SubsequentColorExpandScanline =
312	    I810SubsequentColorExpandScanline;
313   }
314
315   /* Possible todo: Image writes w/ non-GXCOPY rop.
316    */
317
318   I810SelectBuffer(pScrn, I810_SELECT_FRONT);
319
320   return XAAInit(pScreen, infoPtr);
321}
322