xref: /haiku/src/add-ons/accelerants/ati/rage128_draw.cpp (revision 2222d0559df303a9846a2fad53741f8b20b14d7c)
1 /*
2 	Haiku ATI video driver adapted from the X.org ATI driver.
3 
4 	Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
5 						 Precision Insight, Inc., Cedar Park, Texas, and
6 						 VA Linux Systems Inc., Fremont, California.
7 
8 	Copyright 2009 Haiku, Inc.  All rights reserved.
9 	Distributed under the terms of the MIT license.
10 
11 	Authors:
12 	Gerald Zajac 2009
13 */
14 
15 
16 #include "accelerant.h"
17 #include "rage128.h"
18 
19 
20 
21 
22 void
23 Rage128_EngineFlush()
24 {
25 	// Flush all dirty data in the Pixel Cache to memory.
26 
27 	OUTREGM(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, R128_PC_FLUSH_ALL);
28 
29 	for (int i = 0; i < R128_TIMEOUT; i++) {
30 		if ( ! (INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY))
31 			break;
32 	}
33 }
34 
35 
36 void
37 Rage128_EngineReset()
38 {
39 	// Reset graphics card to known state.
40 
41 	Rage128_EngineFlush();
42 
43 	uint32 clockCntlIndex = INREG(R128_CLOCK_CNTL_INDEX);
44 	uint32 mclkCntl = GetPLLReg(R128_MCLK_CNTL);
45 
46 	SetPLLReg(R128_MCLK_CNTL, mclkCntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP);
47 
48 	uint32 genResetCntl = INREG(R128_GEN_RESET_CNTL);
49 
50 	OUTREG(R128_GEN_RESET_CNTL, genResetCntl | R128_SOFT_RESET_GUI);
51 	INREG(R128_GEN_RESET_CNTL);
52 	OUTREG(R128_GEN_RESET_CNTL, genResetCntl & ~R128_SOFT_RESET_GUI);
53 	INREG(R128_GEN_RESET_CNTL);
54 
55 	SetPLLReg(R128_MCLK_CNTL, mclkCntl);
56 	OUTREG(R128_CLOCK_CNTL_INDEX, clockCntlIndex);
57 	OUTREG(R128_GEN_RESET_CNTL, genResetCntl);
58 }
59 
60 
61 void
62 Rage128_EngineInit(const DisplayModeEx& mode)
63 {
64 	// Initialize the acceleration hardware.
65 
66 	SharedInfo& si = *gInfo.sharedInfo;
67 
68 	TRACE("Rage128_EngineInit()  bits/pixel: %d\n", mode.bitsPerPixel);
69 
70 	OUTREG(R128_SCALE_3D_CNTL, 0);
71 	Rage128_EngineReset();
72 
73 	uint32 dataType = 0;
74 
75 	switch (mode.bitsPerPixel) {
76 	case 8:
77 		dataType = 2;
78 		break;
79 	case 15:
80 		dataType = 3;
81 		break;
82 	case 16:
83 		dataType = 4;
84 		break;
85 	case 32:
86 		dataType = 6;
87 		break;
88 	default:
89 		TRACE("Unsupported color depth: %d bits/pixel\n", mode.bitsPerPixel);
90 	}
91 
92 	gInfo.WaitForFifo(2);
93 	OUTREG(R128_DEFAULT_OFFSET, gInfo.sharedInfo->frameBufferOffset);
94 	OUTREG(R128_DEFAULT_PITCH, mode.timing.h_display / 8);
95 
96 	gInfo.WaitForFifo(4);
97 	OUTREG(R128_AUX_SC_CNTL, 0);
98 	OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX
99 										| R128_DEFAULT_SC_BOTTOM_MAX));
100 	OUTREG(R128_SC_TOP_LEFT, 0);
101 	OUTREG(R128_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX
102 								| R128_DEFAULT_SC_BOTTOM_MAX));
103 
104 	si.r128_dpGuiMasterCntl = ((dataType << R128_GMC_DST_DATATYPE_SHIFT)
105 								| R128_GMC_CLR_CMP_CNTL_DIS
106 								| R128_GMC_AUX_CLIP_DIS);
107 	gInfo.WaitForFifo(1);
108 	OUTREG(R128_DP_GUI_MASTER_CNTL, (si.r128_dpGuiMasterCntl
109 									| R128_GMC_BRUSH_SOLID_COLOR
110 									| R128_GMC_SRC_DATATYPE_COLOR));
111 
112 	gInfo.WaitForFifo(8);
113 	OUTREG(R128_DST_BRES_ERR, 0);
114 	OUTREG(R128_DST_BRES_INC, 0);
115 	OUTREG(R128_DST_BRES_DEC, 0);
116 	OUTREG(R128_DP_BRUSH_FRGD_CLR, 0xffffffff);
117 	OUTREG(R128_DP_BRUSH_BKGD_CLR, 0x00000000);
118 	OUTREG(R128_DP_SRC_FRGD_CLR, 0xffffffff);
119 	OUTREG(R128_DP_SRC_BKGD_CLR, 0x00000000);
120 	OUTREG(R128_DP_WRITE_MASK, 0xffffffff);
121 
122 	gInfo.WaitForFifo(1);
123 	OUTREGM(R128_DP_DATATYPE, 0, R128_HOST_BIG_ENDIAN_EN);
124 
125 	gInfo.WaitForIdle();
126 }
127 
128 
129 void
130 Rage128_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, uint32 count)
131 {
132 	(void)et;		// avoid compiler warning for unused arg
133 
134 	gInfo.WaitForFifo(3);
135 	OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl
136 									| R128_GMC_BRUSH_SOLID_COLOR
137 									| R128_GMC_SRC_DATATYPE_COLOR
138 									| R128_ROP3_P));	// use GXcopy for rop
139 
140 	OUTREG(R128_DP_BRUSH_FRGD_CLR, color);
141 	OUTREG(R128_DP_CNTL, R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
142 
143 	while (count--) {
144 		int x = pList->left;
145 		int y = pList->top;
146 		int w = pList->right - x + 1;
147 		int h = pList->bottom - y + 1;
148 
149 		gInfo.WaitForFifo(2);
150 		OUTREG(R128_DST_Y_X, (y << 16) | x);
151 		OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h);
152 
153 		pList++;
154 	}
155 }
156 
157 
158 void
159 Rage128_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count)
160 {
161 	(void)et;		// avoid compiler warning for unused arg
162 
163 	gInfo.WaitForFifo(2);
164 	OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl
165 									| R128_GMC_BRUSH_SOLID_COLOR
166 									| R128_GMC_SRC_DATATYPE_COLOR
167 									| R128_ROP3_P));	// use GXcopy for rop
168 
169 	OUTREG(R128_DP_BRUSH_FRGD_CLR, color);
170 
171 	while (count--) {
172 		int y = *pList++;
173 		int x = *pList++;
174 		int w = *pList++ - x + 1;
175 
176 		if (w <= 0)
177 			continue;	// discard span with zero or negative width
178 
179 		gInfo.WaitForFifo(2);
180 		OUTREG(R128_DST_Y_X, (y << 16) | x);
181 		OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | 1);
182 	}
183 }
184 
185 
186 void
187 Rage128_InvertRectangle(engine_token *et, fill_rect_params *pList, uint32 count)
188 {
189 	(void)et;		// avoid compiler warning for unused arg
190 
191 	gInfo.WaitForFifo(2);
192 	OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl
193 									| R128_GMC_BRUSH_NONE
194 									| R128_GMC_SRC_DATATYPE_COLOR
195 									| R128_DP_SRC_SOURCE_MEMORY
196 									| R128_ROP3_Dn));	// use GXinvert for rop
197 
198 	OUTREG(R128_DP_CNTL, R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
199 
200 	while (count--) {
201 		int x = pList->left;
202 		int y = pList->top;
203 		int w = pList->right - x + 1;
204 		int h = pList->bottom - y + 1;
205 
206 		gInfo.WaitForFifo(2);
207 		OUTREG(R128_DST_Y_X, (y << 16) | x);
208 		OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h);
209 
210 		pList++;
211 	}
212 }
213 
214 
215 void
216 Rage128_ScreenToScreenBlit(engine_token *et, blit_params *pList, uint32 count)
217 {
218 	(void)et;		// avoid compiler warning for unused arg
219 
220 	gInfo.WaitForFifo(1);
221 	OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl
222 									| R128_GMC_BRUSH_NONE
223 									| R128_GMC_SRC_DATATYPE_COLOR
224 									| R128_DP_SRC_SOURCE_MEMORY
225 									| R128_ROP3_S));	// use GXcopy for rop
226 
227 	while (count--) {
228 		int cmd = 0;
229 		int src_x = pList->src_left;
230 		int src_y = pList->src_top;
231 		int dest_x = pList->dest_left;
232 		int dest_y = pList->dest_top;
233 		int width = pList->width;
234 		int height = pList->height;
235 
236 		if (dest_x <= src_x) {
237 			cmd |= R128_DST_X_LEFT_TO_RIGHT;
238 		} else {
239 			src_x += width;
240 			dest_x += width;
241 		}
242 
243 		if (dest_y <= src_y) {
244 			cmd |= R128_DST_Y_TOP_TO_BOTTOM;
245 		} else {
246 			src_y += height;
247 			dest_y += height;
248 		}
249 
250 		gInfo.WaitForFifo(4);
251 		OUTREG(R128_DP_CNTL, cmd);
252 		OUTREG(R128_SRC_Y_X, (src_y << 16) | src_x);
253 		OUTREG(R128_DST_Y_X, (dest_y << 16) | dest_x);
254 		OUTREG(R128_DST_HEIGHT_WIDTH, ((height + 1) << 16) | (width + 1));
255 
256 		pList ++;
257 	}
258 }
259