vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / ati / rage128_draw.cpp
blob710e5d233cdbe236c81f23d69676a6cc4d92637d
1 /*
2 Haiku ATI video driver adapted from the X.org ATI driver.
4 Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
5 Precision Insight, Inc., Cedar Park, Texas, and
6 VA Linux Systems Inc., Fremont, California.
8 Copyright 2009 Haiku, Inc. All rights reserved.
9 Distributed under the terms of the MIT license.
11 Authors:
12 Gerald Zajac 2009
16 #include "accelerant.h"
17 #include "rage128.h"
22 void
23 Rage128_EngineFlush()
25 // Flush all dirty data in the Pixel Cache to memory.
27 OUTREGM(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, R128_PC_FLUSH_ALL);
29 for (int i = 0; i < R128_TIMEOUT; i++) {
30 if ( ! (INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY))
31 break;
36 void
37 Rage128_EngineReset()
39 // Reset graphics card to known state.
41 Rage128_EngineFlush();
43 uint32 clockCntlIndex = INREG(R128_CLOCK_CNTL_INDEX);
44 uint32 mclkCntl = GetPLLReg(R128_MCLK_CNTL);
46 SetPLLReg(R128_MCLK_CNTL, mclkCntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP);
48 uint32 genResetCntl = INREG(R128_GEN_RESET_CNTL);
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);
55 SetPLLReg(R128_MCLK_CNTL, mclkCntl);
56 OUTREG(R128_CLOCK_CNTL_INDEX, clockCntlIndex);
57 OUTREG(R128_GEN_RESET_CNTL, genResetCntl);
61 void
62 Rage128_EngineInit(const DisplayModeEx& mode)
64 // Initialize the acceleration hardware.
66 SharedInfo& si = *gInfo.sharedInfo;
68 TRACE("Rage128_EngineInit() bits/pixel: %d\n", mode.bitsPerPixel);
70 OUTREG(R128_SCALE_3D_CNTL, 0);
71 Rage128_EngineReset();
73 uint32 dataType = 0;
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);
92 gInfo.WaitForFifo(2);
93 OUTREG(R128_DEFAULT_OFFSET, gInfo.sharedInfo->frameBufferOffset);
94 OUTREG(R128_DEFAULT_PITCH, mode.timing.h_display / 8);
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));
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));
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);
122 gInfo.WaitForFifo(1);
123 OUTREGM(R128_DP_DATATYPE, 0, R128_HOST_BIG_ENDIAN_EN);
125 gInfo.WaitForIdle();
129 void
130 Rage128_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, uint32 count)
132 (void)et; // avoid compiler warning for unused arg
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
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);
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;
149 gInfo.WaitForFifo(2);
150 OUTREG(R128_DST_Y_X, (y << 16) | x);
151 OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h);
153 pList++;
158 void
159 Rage128_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count)
161 (void)et; // avoid compiler warning for unused arg
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
169 OUTREG(R128_DP_BRUSH_FRGD_CLR, color);
171 while (count--) {
172 int y = *pList++;
173 int x = *pList++;
174 int w = *pList++ - x + 1;
176 if (w <= 0)
177 continue; // discard span with zero or negative width
179 gInfo.WaitForFifo(2);
180 OUTREG(R128_DST_Y_X, (y << 16) | x);
181 OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | 1);
186 void
187 Rage128_InvertRectangle(engine_token *et, fill_rect_params *pList, uint32 count)
189 (void)et; // avoid compiler warning for unused arg
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
198 OUTREG(R128_DP_CNTL, R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
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;
206 gInfo.WaitForFifo(2);
207 OUTREG(R128_DST_Y_X, (y << 16) | x);
208 OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h);
210 pList++;
215 void
216 Rage128_ScreenToScreenBlit(engine_token *et, blit_params *pList, uint32 count)
218 (void)et; // avoid compiler warning for unused arg
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
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;
236 if (dest_x <= src_x) {
237 cmd |= R128_DST_X_LEFT_TO_RIGHT;
238 } else {
239 src_x += width;
240 dest_x += width;
243 if (dest_y <= src_y) {
244 cmd |= R128_DST_Y_TOP_TO_BOTTOM;
245 } else {
246 src_y += height;
247 dest_y += height;
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));
256 pList ++;