i810_xaa.c revision 03b705cf
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 "xf86.h"
40#include "xaarop.h"
41#include "i810.h"
42
43static void
44I810SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
45			       int fg, int bg, int rop,
46			       unsigned int planemask)
47{
48   I810Ptr pI810 = I810PTR(pScrn);
49
50   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
51      ErrorF("I810SetupFor8x8PatternColorExpand\n");
52
53   /* FULL_MONO_PAT_BLT, p176 */
54   pI810->BR[0] = (BR00_BITBLT_CLIENT | BR00_OP_MONO_PAT_BLT | 0x9);
55   pI810->BR[18] = bg;
56   pI810->BR[19] = fg;
57   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
58   pI810->BR[13] |= I810PatternROP[rop] << 16;
59   if (bg == -1)
60      pI810->BR[13] |= BR13_MONO_PATN_TRANS;
61}
62
63static void
64I810SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
65				     int x, int y, int w, int h)
66{
67   I810Ptr pI810 = I810PTR(pScrn);
68   int addr =
69	 pI810->bufferOffset + (y * pScrn->displayWidth + x) * pI810->cpp;
70
71   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
72      ErrorF("I810Subsequent8x8PatternColorExpand\n");
73
74   {
75      BEGIN_LP_RING(12);
76      OUT_RING(pI810->BR[0] | ((y << 5) & BR00_PAT_VERT_ALIGN));
77      OUT_RING(pI810->BR[13]);
78      OUT_RING((h << 16) | (w * pI810->cpp));
79      OUT_RING(addr);
80      OUT_RING(pI810->BR[13] & 0xFFFF);	/* src pitch */
81      OUT_RING(addr);			/* src addr */
82      OUT_RING(0);			/* transparency color */
83      OUT_RING(pI810->BR[18]);		/* bg */
84      OUT_RING(pI810->BR[19]);		/* fg */
85      OUT_RING(pattx);			/* pattern data */
86      OUT_RING(patty);
87      OUT_RING(0);
88      ADVANCE_LP_RING();
89   }
90}
91
92static void
93I810GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
94{
95   I810Ptr pI810 = I810PTR(pScrn);
96   XAAInfoRecPtr infoPtr = pI810->AccelInfoRec;
97
98   if (pI810->nextColorExpandBuf == pI810->NumScanlineColorExpandBuffers)
99      I810Sync(pScrn);
100
101   infoPtr->ScanlineColorExpandBuffers[0] =
102	 pI810->ScanlineColorExpandBuffers[pI810->nextColorExpandBuf];
103
104   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
105      ErrorF("using color expand buffer %d\n", pI810->nextColorExpandBuf);
106
107   pI810->nextColorExpandBuf++;
108}
109
110static void
111I810SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
112					       int fg, int bg, int rop,
113					       unsigned int planemask)
114{
115   I810Ptr pI810 = I810PTR(pScrn);
116
117   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
118      ErrorF("I810SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
119	     fg, bg, rop, planemask);
120
121   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
122   pI810->BR[13] |= I810CopyROP[rop] << 16;
123   pI810->BR[13] |= (1 << 27);
124   if (bg == -1)
125      pI810->BR[13] |= BR13_MONO_TRANSPCY;
126
127   pI810->BR[18] = bg;
128   pI810->BR[19] = fg;
129
130   I810GetNextScanlineColorExpandBuffer(pScrn);
131}
132
133static void
134I810SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
135						 int x, int y,
136						 int w, int h, int skipleft)
137{
138   I810Ptr pI810 = I810PTR(pScrn);
139
140   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
141      ErrorF("I810SubsequentScanlineCPUToScreenColorExpandFill "
142	     "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
143
144   pI810->BR[0] = BR00_BITBLT_CLIENT | BR00_OP_MONO_SRC_COPY_BLT | 0x06;
145   pI810->BR[9] = (pI810->bufferOffset +
146		   (y * pScrn->displayWidth + x) * pI810->cpp);
147   pI810->BR[14] = ((1 << 16) | (w * pI810->cpp));
148   pI810->BR[11] = ((w + 31) / 32) - 1;
149}
150
151static void
152I810SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
153{
154   I810Ptr pI810 = I810PTR(pScrn);
155
156   pI810->BR[12] = (pI810->AccelInfoRec->ScanlineColorExpandBuffers[0] -
157		    pI810->FbBase);
158
159   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
160      ErrorF("I810SubsequentColorExpandScanline %d (addr %x)\n",
161	     bufno, pI810->BR[12]);
162
163   {
164      BEGIN_LP_RING(8);
165      OUT_RING(pI810->BR[0]);
166      OUT_RING(pI810->BR[13]);
167      OUT_RING(pI810->BR[14]);
168      OUT_RING(pI810->BR[9]);
169      OUT_RING(pI810->BR[11]);
170      OUT_RING(pI810->BR[12]);		/* srcaddr */
171      OUT_RING(pI810->BR[18]);
172      OUT_RING(pI810->BR[19]);
173      ADVANCE_LP_RING();
174   }
175
176   /* Advance to next scanline.
177    */
178   pI810->BR[9] += pScrn->displayWidth * pI810->cpp;
179   I810GetNextScanlineColorExpandBuffer(pScrn);
180}
181
182/* Emit on gaining VT?
183 */
184#if 0
185static void
186I810EmitInvarientState(ScrnInfoPtr pScrn)
187{
188   I810Ptr pI810 = I810PTR(pScrn);
189
190   BEGIN_LP_RING(10);
191
192   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
193   OUT_RING(GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0);
194   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
195   OUT_RING(0);
196
197   OUT_RING(GFX_OP_COLOR_CHROMA_KEY);
198   OUT_RING(CC1_UPDATE_KILL_WRITE |
199	    CC1_DISABLE_KILL_WRITE |
200	    CC1_UPDATE_COLOR_IDX |
201	    CC1_UPDATE_CHROMA_LOW | CC1_UPDATE_CHROMA_HI | 0);
202   OUT_RING(0);
203   OUT_RING(0);
204
205/*     OUT_RING( CMD_OP_Z_BUFFER_INFO ); */
206/*     OUT_RING( pI810->DepthBuffer.Start | pI810->auxPitchBits); */
207
208   ADVANCE_LP_RING();
209}
210#endif
211
212/* The following function sets up the supported acceleration. Call it
213 * from the FbInit() function in the SVGA driver, or before ScreenInit
214 * in a monolithic server.
215 */
216Bool
217I810AccelInit(ScreenPtr pScreen)
218{
219   XAAInfoRecPtr infoPtr;
220   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
221   I810Ptr pI810 = I810PTR(pScrn);
222
223   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
224      ErrorF("I810AccelInit\n");
225
226   pI810->AccelInfoRec = infoPtr = XAACreateInfoRec();
227   if (!infoPtr)
228      return FALSE;
229
230   pI810->bufferOffset = 0;
231   infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
232   infoPtr->Flags |= PIXMAP_CACHE;
233
234   /* Sync
235    */
236   infoPtr->Sync = I810Sync;
237
238   /* Solid filled rectangles
239    */
240   {
241      infoPtr->SolidFillFlags = NO_PLANEMASK;
242      infoPtr->SetupForSolidFill = I810SetupForSolidFill;
243      infoPtr->SubsequentSolidFillRect = I810SubsequentSolidFillRect;
244   }
245
246   /* Screen to screen copy
247    *   - the transparency op hangs the blit engine, disable for now.
248    */
249   {
250      infoPtr->ScreenToScreenCopyFlags = (0
251					  | NO_PLANEMASK
252					  | NO_TRANSPARENCY | 0);
253
254      infoPtr->SetupForScreenToScreenCopy = I810SetupForScreenToScreenCopy;
255      infoPtr->SubsequentScreenToScreenCopy =
256	    I810SubsequentScreenToScreenCopy;
257   }
258
259   /* 8x8 pattern fills
260    */
261   {
262      infoPtr->SetupForMono8x8PatternFill = I810SetupForMono8x8PatternFill;
263      infoPtr->SubsequentMono8x8PatternFillRect =
264	    I810SubsequentMono8x8PatternFillRect;
265
266      infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
267					  HARDWARE_PATTERN_SCREEN_ORIGIN |
268					  BIT_ORDER_IN_BYTE_MSBFIRST |
269					  NO_PLANEMASK | 0);
270   }
271
272   /* 8x8 color fills - not considered useful for XAA.
273    */
274
275   /* Scanline color expansion - Use the same scheme as the 3.3 driver.
276    *
277    */
278   if (pI810->Scratch.Size != 0) {
279      int i;
280      int width = ALIGN(pScrn->displayWidth, 32) / 8;
281      int nr_buffers = pI810->Scratch.Size / width;
282      unsigned char *ptr = pI810->FbBase + pI810->Scratch.Start;
283
284      pI810->NumScanlineColorExpandBuffers = nr_buffers;
285      pI810->ScanlineColorExpandBuffers = (unsigned char **)
286	    xnfcalloc(nr_buffers, sizeof(unsigned char *));
287
288      for (i = 0; i < nr_buffers; i++, ptr += width)
289	 pI810->ScanlineColorExpandBuffers[i] = ptr;
290
291      infoPtr->ScanlineCPUToScreenColorExpandFillFlags = (NO_PLANEMASK |
292							  ROP_NEEDS_SOURCE |
293							  BIT_ORDER_IN_BYTE_MSBFIRST
294							  | 0);
295
296      infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
297	    xnfcalloc(1, sizeof(unsigned char *));
298      infoPtr->NumScanlineColorExpandBuffers = 1;
299
300      infoPtr->ScanlineColorExpandBuffers[0] =
301	    pI810->ScanlineColorExpandBuffers[0];
302      pI810->nextColorExpandBuf = 0;
303
304      infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
305	    I810SetupForScanlineCPUToScreenColorExpandFill;
306
307      infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
308	    I810SubsequentScanlineCPUToScreenColorExpandFill;
309
310      infoPtr->SubsequentColorExpandScanline =
311	    I810SubsequentColorExpandScanline;
312   }
313
314   /* Possible todo: Image writes w/ non-GXCOPY rop.
315    */
316
317   I810SelectBuffer(pScrn, I810_SELECT_FRONT);
318
319   return XAAInit(pScreen, infoPtr);
320}
321