xref: /haiku/src/add-ons/accelerants/ati/mach64_draw.cpp (revision 80829ec813241c9a702a45e39929286f13c55093)
1 /*
2 	Haiku ATI video driver adapted from the X.org ATI driver.
3 
4 	Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina.
5 	Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
6 
7 	Copyright 2009 Haiku, Inc.  All rights reserved.
8 	Distributed under the terms of the MIT license.
9 
10 	Authors:
11 	Gerald Zajac 2009
12 */
13 
14 
15 #include "accelerant.h"
16 #include "mach64.h"
17 
18 
19 
20 void
Mach64_EngineReset()21 Mach64_EngineReset()
22 {
23 	// Reset engine and then enable it.
24 
25 	uint32 genTestCntl = INREG(GEN_TEST_CNTL) & ~GUI_ENGINE_ENABLE;
26 	OUTREG(GEN_TEST_CNTL, genTestCntl);
27 	OUTREG(GEN_TEST_CNTL, genTestCntl | GUI_ENGINE_ENABLE);
28 
29 	// Ensure engine is not locked up by clearing any FIFO errors.
30 
31 	OUTREG(BUS_CNTL, INREG(BUS_CNTL) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK);
32 }
33 
34 
35 void
Mach64_EngineInit(const DisplayModeEx & mode)36 Mach64_EngineInit(const DisplayModeEx& mode)
37 {
38 	// Initialize the drawing environment and clear the display.
39 
40 	Mach64_EngineReset();
41 
42 	gInfo.WaitForIdle();
43 
44 	OUTREG(MEM_VGA_WP_SEL, 0x00010000);
45 	OUTREG(MEM_VGA_RP_SEL, 0x00010000);
46 
47 	uint32 dpPixWidth = 0;
48 	uint32 dpChainMask = 0;
49 
50 	switch (mode.bitsPerPixel) {
51 	case 8:
52 		dpPixWidth = HOST_8BPP | SRC_8BPP | DST_8BPP;
53 		dpChainMask = DP_CHAIN_8BPP;
54 		break;
55 	case 15:
56 		dpPixWidth = HOST_15BPP | SRC_15BPP | DST_15BPP;
57 		dpChainMask = DP_CHAIN_15BPP;
58 		break;
59 	case 16:
60 		dpPixWidth = HOST_16BPP | SRC_16BPP | DST_16BPP;
61 		dpChainMask = DP_CHAIN_16BPP;
62 		break;
63 	case 32:
64 		dpPixWidth = HOST_32BPP | SRC_32BPP | DST_32BPP;
65 		dpChainMask = DP_CHAIN_32BPP;
66 		break;
67 	}
68 
69 	dpPixWidth |= BYTE_ORDER_LSB_TO_MSB;	// set for little-endian byte order
70 
71 	gInfo.WaitForFifo(3);
72 	OUTREG(DP_PIX_WIDTH, dpPixWidth);
73 	OUTREG(DP_CHAIN_MASK, dpChainMask);
74 
75 	OUTREG(CONTEXT_MASK, 0xffffffff);
76 
77 	gInfo.WaitForFifo(7);
78 	OUTREG(DST_OFF_PITCH, (mode.timing.h_display / 8) << 22);
79 	OUTREG(DST_Y_X, 0);
80 	OUTREG(DST_HEIGHT, 0);
81 	OUTREG(DST_BRES_ERR, 0);
82 	OUTREG(DST_BRES_INC, 0);
83 	OUTREG(DST_BRES_DEC, 0);
84 	OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL);
85 
86 	gInfo.WaitForFifo(6);
87 	OUTREG(SRC_OFF_PITCH, (mode.timing.h_display / 8) << 22);
88 	OUTREG(SRC_Y_X, 0);
89 	OUTREG(SRC_HEIGHT1_WIDTH1, 0x10001);
90 	OUTREG(SRC_Y_X_START, 0);
91 	OUTREG(SRC_HEIGHT2_WIDTH2, 0x10001);
92 	OUTREG(SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT);
93 
94 	gInfo.WaitForFifo(7);
95 	OUTREGM(HOST_CNTL, 0, HOST_BYTE_ALIGN);
96 	OUTREG(PAT_REG0, 0);
97 	OUTREG(PAT_REG1, 0);
98 	OUTREG(PAT_CNTL, 0);
99 
100 	OUTREG(SC_LEFT_RIGHT, ((mode.timing.h_display << 16) | 0 ));
101 	OUTREG(SC_TOP_BOTTOM, ((mode.timing.v_display << 16) | 0 ));
102 
103 	gInfo.WaitForFifo(9);
104 	OUTREG(DP_BKGD_CLR, 0);
105 	OUTREG(DP_FRGD_CLR, 0xffffffff);
106 	OUTREG(DP_WRITE_MASK, 0xffffffff);
107 	OUTREG(DP_MIX, (MIX_SRC << 16) | MIX_DST);
108 	OUTREG(DP_SRC, FRGD_SRC_FRGD_CLR);
109 
110 	OUTREG(CLR_CMP_CLR, 0);
111 	OUTREG(CLR_CMP_MASK, 0xffffffff);
112 	OUTREG(CLR_CMP_CNTL, 0);
113 
114 	gInfo.WaitForIdle();
115 }
116 
117 
118 void
Mach64_FillRectangle(engine_token * et,uint32 color,fill_rect_params * pList,uint32 count)119 Mach64_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, uint32 count)
120 {
121 	(void)et;		// avoid compiler warning for unused arg
122 
123 	gInfo.WaitForFifo(4);
124 	OUTREG(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE);
125 	OUTREG(DP_FRGD_CLR, color);
126 	OUTREG(DP_MIX, (MIX_SRC << 16) | MIX_DST);
127 	OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL);
128 
129 	while (count--) {
130 		int x = pList->left;
131 		int y = pList->top;
132 		int w = pList->right - x + 1;
133 		int h = pList->bottom - y + 1;
134 
135 		gInfo.WaitForFifo(2);
136 		OUTREG(DST_Y_X, (x << 16) | y);
137 		OUTREG(DST_HEIGHT_WIDTH, (w << 16) | h);
138 
139 		pList++;
140 	}
141 }
142 
143 
144 void
Mach64_FillSpan(engine_token * et,uint32 color,uint16 * pList,uint32 count)145 Mach64_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count)
146 {
147 	(void)et;		// avoid compiler warning for unused arg
148 
149 	gInfo.WaitForFifo(4);
150 	OUTREG(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE);
151 	OUTREG(DP_FRGD_CLR, color);
152 	OUTREG(DP_MIX, (MIX_SRC << 16) | MIX_DST);
153 	OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL);
154 
155 	while (count--) {
156 		int y = *pList++;
157 		int x = *pList++;
158 		int w = *pList++ - x + 1;
159 
160 		if (w <= 0)
161 			continue;	// discard span with zero or negative width
162 
163 		gInfo.WaitForFifo(2);
164 		OUTREG(DST_Y_X, (x << 16) | y);
165 		OUTREG(DST_HEIGHT_WIDTH, (w << 16) | 1);
166 	}
167 }
168 
169 
170 void
Mach64_InvertRectangle(engine_token * et,fill_rect_params * pList,uint32 count)171 Mach64_InvertRectangle(engine_token *et, fill_rect_params *pList, uint32 count)
172 {
173 	(void)et;		// avoid compiler warning for unused arg
174 
175 	gInfo.WaitForFifo(3);
176 	OUTREG(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE);
177 	OUTREG(DP_MIX, MIX_NOT_DST << 16);
178 	OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL);
179 
180 	while (count--) {
181 		int x = pList->left;
182 		int y = pList->top;
183 		int w = pList->right - x + 1;
184 		int h = pList->bottom - y + 1;
185 
186 		gInfo.WaitForFifo(2);
187 		OUTREG(DST_Y_X, (x << 16) | y);
188 		OUTREG(DST_HEIGHT_WIDTH, (w << 16) | h);
189 
190 		pList++;
191 	}
192 }
193 
194 
195 void
Mach64_ScreenToScreenBlit(engine_token * et,blit_params * pList,uint32 count)196 Mach64_ScreenToScreenBlit(engine_token *et, blit_params *pList, uint32 count)
197 {
198 	(void)et;		// avoid compiler warning for unused arg
199 
200 	gInfo.WaitForFifo(2);
201 	OUTREG(DP_SRC, FRGD_SRC_BLIT);
202 	OUTREG(DP_MIX, MIX_SRC << 16);
203 
204 	while (count--) {
205 		int cmd = DST_LAST_PEL;
206 		int src_x = pList->src_left;
207 		int src_y = pList->src_top;
208 		int dest_x = pList->dest_left;
209 		int dest_y = pList->dest_top;
210 		int width = pList->width;
211 		int height = pList->height;
212 
213 		if (dest_x <= src_x) {
214 			cmd |= DST_X_LEFT_TO_RIGHT;
215 		} else {
216 			src_x += width;
217 			dest_x += width;
218 		}
219 
220 		if (dest_y <= src_y) {
221 			cmd |= DST_Y_TOP_TO_BOTTOM;
222 		} else {
223 			src_y += height;
224 			dest_y += height;
225 		}
226 
227 		gInfo.WaitForFifo(5);
228 		OUTREG(DST_CNTL, cmd);
229 		OUTREG(SRC_Y_X, (src_x << 16) | src_y);
230 		OUTREG(SRC_HEIGHT1_WIDTH1, ((width + 1) << 16) | (height + 1));
231 		OUTREG(DST_Y_X, (dest_x << 16) | dest_y);
232 		OUTREG(DST_HEIGHT_WIDTH, ((width + 1) << 16) | (height + 1));
233 
234 		pList ++;
235 	}
236 }
237