2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 * Keith Whitwell <keith@tungstengraphics.com>
35 * Nicolai Haehnle <prefect_@gmx.net>
45 #include "swrast/swrast.h"
47 #include "r300_context.h"
48 #include "radeon_ioctl.h"
49 #include "r300_ioctl.h"
50 #include "r300_cmdbuf.h"
51 #include "r300_state.h"
52 #include "r300_program.h"
53 #include "radeon_reg.h"
54 #include "r300_emit.h"
60 #define CLEARBUFFER_COLOR 0x1
61 #define CLEARBUFFER_DEPTH 0x2
62 #define CLEARBUFFER_STENCIL 0x4
64 static void r300ClearBuffer(r300ContextPtr r300
, int flags
, int buffer
)
66 GLcontext
* ctx
= r300
->radeon
.glCtx
;
67 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
68 GLuint cboffset
, cbpitch
;
69 drm_r300_cmd_header_t
* cmd2
;
71 r300ContextPtr rmesa
=r300
;
77 if (RADEON_DEBUG
& DEBUG_IOCTL
)
78 fprintf(stderr
, "%s: %s buffer (%i,%i %ix%i)\n",
79 __FUNCTION__
, buffer
? "back" : "front",
80 dPriv
->x
, dPriv
->y
, dPriv
->w
, dPriv
->h
);
83 cboffset
= r300
->radeon
.radeonScreen
->backOffset
;
84 cbpitch
= r300
->radeon
.radeonScreen
->backPitch
;
86 cboffset
= r300
->radeon
.radeonScreen
->frontOffset
;
87 cbpitch
= r300
->radeon
.radeonScreen
->frontPitch
;
90 cboffset
+= r300
->radeon
.radeonScreen
->fbLocation
;
93 R300_STATECHANGE(r300
, vir
[0]);
94 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->unchecked_state
.count
= 1;
95 r300
->hw
.vir
[0].cmd
[1] = 0x21030003;
97 R300_STATECHANGE(r300
, vir
[1]);
98 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->unchecked_state
.count
= 1;
99 r300
->hw
.vir
[1].cmd
[1] = 0xF688F688;
101 R300_STATECHANGE(r300
, vic
);
102 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_0
] = 0x00000001;
103 r300
->hw
.vic
.cmd
[R300_VIC_CNTL_1
] = 0x00000405;
105 R300_STATECHANGE(r300
, vof
);
106 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
107 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
108 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = 0; /* no textures */
110 R300_STATECHANGE(r300
, txe
);
111 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0;
113 R300_STATECHANGE(r300
, vpt
);
114 r300
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(1.0);
115 r300
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(dPriv
->x
);
116 r300
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(1.0);
117 r300
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(dPriv
->y
);
118 r300
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(1.0);
119 r300
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(0.0);
121 R300_STATECHANGE(r300
, at
);
122 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = 0;
124 R300_STATECHANGE(r300
, bld
);
125 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = 0;
126 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = 0;
128 R300_STATECHANGE(r300
, cb
);
129 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = cboffset
;
130 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = cbpitch
| R300_COLOR_UNKNOWN_22_23
;
132 R300_STATECHANGE(r300
, unk221C
);
133 r300
->hw
.unk221C
.cmd
[1] = R300_221C_CLEAR
;
135 R300_STATECHANGE(r300
, ps
);
136 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
137 ((dPriv
->w
* 6) << R300_POINTSIZE_X_SHIFT
) |
138 ((dPriv
->h
* 6) << R300_POINTSIZE_Y_SHIFT
);
140 R300_STATECHANGE(r300
, ri
);
141 for(i
= 1; i
<= 8; ++i
)
142 r300
->hw
.ri
.cmd
[i
] = R300_RS_INTERP_USED
;
144 R300_STATECHANGE(r300
, rc
);
145 /* The second constant is needed to get glxgears display anything .. */
146 r300
->hw
.rc
.cmd
[1] = R300_RS_CNTL_0_UNKNOWN_7
| R300_RS_CNTL_0_UNKNOWN_18
;
147 r300
->hw
.rc
.cmd
[2] = 0;
149 R300_STATECHANGE(r300
, rr
);
150 ((drm_r300_cmd_header_t
*)r300
->hw
.rr
.cmd
)->unchecked_state
.count
= 1;
151 r300
->hw
.rr
.cmd
[1] = 0x00004000;
153 R300_STATECHANGE(r300
, cmk
);
154 if (flags
& CLEARBUFFER_COLOR
) {
155 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] =
156 (ctx
->Color
.ColorMask
[BCOMP
] ? R300_COLORMASK0_B
: 0) |
157 (ctx
->Color
.ColorMask
[GCOMP
] ? R300_COLORMASK0_G
: 0) |
158 (ctx
->Color
.ColorMask
[RCOMP
] ? R300_COLORMASK0_R
: 0) |
159 (ctx
->Color
.ColorMask
[ACOMP
] ? R300_COLORMASK0_A
: 0);
161 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = 0;
164 R300_STATECHANGE(r300
, fp
);
165 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0; /* 1 pass, no textures */
166 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0; /* no temporaries */
167 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0; /* no offset, one ALU instr */
168 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
169 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
170 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
171 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = R300_PFS_NODE_LAST_NODE
;
173 R300_STATECHANGE(r300
, fpi
[0]);
174 R300_STATECHANGE(r300
, fpi
[1]);
175 R300_STATECHANGE(r300
, fpi
[2]);
176 R300_STATECHANGE(r300
, fpi
[3]);
177 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[0].cmd
)->unchecked_state
.count
= 1;
178 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[1].cmd
)->unchecked_state
.count
= 1;
179 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[2].cmd
)->unchecked_state
.count
= 1;
180 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[3].cmd
)->unchecked_state
.count
= 1;
183 r300
->hw
.fpi
[0].cmd
[1] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
184 r300
->hw
.fpi
[1].cmd
[1] = FP_SELC(0,NO
,XYZ
,FP_TMP(0),0,0);
185 r300
->hw
.fpi
[2].cmd
[1] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
186 r300
->hw
.fpi
[3].cmd
[1] = FP_SELA(0,NO
,W
,FP_TMP(0),0,0);
188 R300_STATECHANGE(r300
, pvs
);
189 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
190 (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
191 (0 << R300_PVS_CNTL_1_POS_END_SHIFT
) |
192 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
193 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0; /* no parameters */
194 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
195 (1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
197 R300_STATECHANGE(r300
, vpi
);
198 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->unchecked_state
.count
= 8;
201 r300
->hw
.vpi
.cmd
[1] = VP_OUT(ADD
,OUT
,0,XYZW
);
202 r300
->hw
.vpi
.cmd
[2] = VP_IN(IN
,0);
203 r300
->hw
.vpi
.cmd
[3] = VP_ZERO();
204 r300
->hw
.vpi
.cmd
[4] = 0;
207 r300
->hw
.vpi
.cmd
[5] = VP_OUT(ADD
,OUT
,1,XYZW
);
208 r300
->hw
.vpi
.cmd
[6] = VP_IN(IN
,1);
209 r300
->hw
.vpi
.cmd
[7] = VP_ZERO();
210 r300
->hw
.vpi
.cmd
[8] = 0;
212 R300_STATECHANGE(r300
, zs
);
213 if (flags
& CLEARBUFFER_DEPTH
) {
214 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
215 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= 0x6; // test and write
216 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
217 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
219 R300_STATECHANGE(r300, zb);
220 r300->hw.zb.cmd[R300_ZB_OFFSET] =
222 r300->radeon.radeonScreen->frontOffset +
223 r300->radeon.radeonScreen->fbLocation;
224 r300->hw.zb.cmd[R300_ZB_PITCH] =
225 r300->radeon.radeonScreen->depthPitch;
228 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
229 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_DISABLED_1
; // disable
230 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
233 R300_STATECHANGE(r300
, zs
);
234 if (flags
& CLEARBUFFER_STENCIL
) {
235 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= ~R300_RB3D_STENCIL_ENABLE
;
236 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_STENCIL_ENABLE
;
237 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
238 ~((R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
239 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
240 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
241 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
242 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
243 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
244 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
245 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
246 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
247 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
) ;
248 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] = r300
->state
.stencil
.clear
;
251 /* Make sure we have enough space */
252 r300EnsureCmdBufSpace(r300
, r300
->hw
.max_state_size
+ 9+8, __FUNCTION__
);
256 R300_STATECHANGE(r300
, cb
);
257 reg_start(R300_RB3D_COLOROFFSET0
, 0);
260 reg_start(R300_RB3D_COLORPITCH0
, 0);
261 e32(cbpitch
| R300_COLOR_UNKNOWN_22_23
);
263 R300_STATECHANGE(r300
, cmk
);
264 reg_start(R300_RB3D_COLORMASK
, 0);
266 if (flags
& CLEARBUFFER_COLOR
) {
267 e32((ctx
->Color
.ColorMask
[BCOMP
] ? R300_COLORMASK0_B
: 0) |
268 (ctx
->Color
.ColorMask
[GCOMP
] ? R300_COLORMASK0_G
: 0) |
269 (ctx
->Color
.ColorMask
[RCOMP
] ? R300_COLORMASK0_R
: 0) |
270 (ctx
->Color
.ColorMask
[ACOMP
] ? R300_COLORMASK0_A
: 0));
275 R300_STATECHANGE(r300
, zs
);
276 reg_start(R300_RB3D_ZSTENCIL_CNTL_0
, 2);
281 t1
= r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
];
282 t2
= r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
];
284 if (flags
& CLEARBUFFER_DEPTH
) {
285 t1
&= R300_RB3D_STENCIL_ENABLE
;
286 t1
|= 0x6; // test and write
288 t2
&= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
289 t2
|= (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
291 R300_STATECHANGE(r300, zb);
292 r300->hw.zb.cmd[R300_ZB_OFFSET] =
294 r300->radeon.radeonScreen->frontOffset +
295 r300->radeon.radeonScreen->fbLocation;
296 r300->hw.zb.cmd[R300_ZB_PITCH] =
297 r300->radeon.radeonScreen->depthPitch;
300 t1
&= R300_RB3D_STENCIL_ENABLE
;
301 t1
|= R300_RB3D_Z_DISABLED_1
; // disable
303 t2
&= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
306 if (flags
& CLEARBUFFER_STENCIL
) {
307 t1
&= ~R300_RB3D_STENCIL_ENABLE
;
308 t1
|= R300_RB3D_STENCIL_ENABLE
;
311 ~((R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
313 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
314 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
315 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
316 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
317 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
318 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
319 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
320 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
) ;
325 e32(r300
->state
.stencil
.clear
);
330 cmd2
= (drm_r300_cmd_header_t
*)r300AllocCmdBuf(r300
, 9, __FUNCTION__
);
331 cmd2
[0].packet3
.cmd_type
= R300_CMD_PACKET3
;
332 cmd2
[0].packet3
.packet
= R300_CMD_PACKET3_CLEAR
;
333 cmd2
[1].u
= r300PackFloat32(dPriv
->w
/ 2.0);
334 cmd2
[2].u
= r300PackFloat32(dPriv
->h
/ 2.0);
335 cmd2
[3].u
= r300PackFloat32(ctx
->Depth
.Clear
);
336 cmd2
[4].u
= r300PackFloat32(1.0);
337 cmd2
[5].u
= r300PackFloat32(ctx
->Color
.ClearColor
[0]);
338 cmd2
[6].u
= r300PackFloat32(ctx
->Color
.ClearColor
[1]);
339 cmd2
[7].u
= r300PackFloat32(ctx
->Color
.ClearColor
[2]);
340 cmd2
[8].u
= r300PackFloat32(ctx
->Color
.ClearColor
[3]);
344 static void r300EmitClearState(GLcontext
* ctx
)
346 r300ContextPtr r300
= R300_CONTEXT(ctx
);
347 r300ContextPtr rmesa
=r300
;
348 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
352 R300_STATECHANGE(r300
, vir
[0]);
353 reg_start(R300_VAP_INPUT_ROUTE_0_0
, 0);
356 R300_STATECHANGE(r300
, vir
[1]);
357 reg_start(R300_VAP_INPUT_ROUTE_1_0
, 0);
360 R300_STATECHANGE(r300
, vic
);
361 reg_start(R300_VAP_INPUT_CNTL_0
, 1);
365 R300_STATECHANGE(r300
, vof
);
366 reg_start(R300_VAP_OUTPUT_VTX_FMT_0
, 1);
367 e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
);
368 e32(0); /* no textures */
371 R300_STATECHANGE(r300
, txe
);
372 reg_start(R300_TX_ENABLE
, 0);
375 R300_STATECHANGE(r300
, vpt
);
376 reg_start(R300_SE_VPORT_XSCALE
, 5);
384 R300_STATECHANGE(r300
, at
);
385 reg_start(R300_PP_ALPHA_TEST
, 0);
388 R300_STATECHANGE(r300
, bld
);
389 reg_start(R300_RB3D_CBLEND
, 1);
393 R300_STATECHANGE(r300
, unk221C
);
394 reg_start(0x221C, 0);
395 e32(R300_221C_CLEAR
);
397 R300_STATECHANGE(r300
, ps
);
398 reg_start(R300_RE_POINTSIZE
, 0);
399 e32(((dPriv
->w
* 6) << R300_POINTSIZE_X_SHIFT
) |
400 ((dPriv
->h
* 6) << R300_POINTSIZE_Y_SHIFT
));
402 R300_STATECHANGE(r300
, ri
);
403 reg_start(R300_RS_INTERP_0
, 8);
404 for(i
= 0; i
< 8; ++i
){
405 e32(R300_RS_INTERP_USED
);
408 R300_STATECHANGE(r300
, rc
);
409 /* The second constant is needed to get glxgears display anything .. */
410 reg_start(R300_RS_CNTL_0
, 1);
411 e32(R300_RS_CNTL_0_UNKNOWN_7
| R300_RS_CNTL_0_UNKNOWN_18
);
414 R300_STATECHANGE(r300
, rr
);
415 reg_start(R300_RS_ROUTE_0
, 0);
418 R300_STATECHANGE(r300
, fp
);
419 reg_start(R300_PFS_CNTL_0
, 2);
423 reg_start(R300_PFS_NODE_0
, 3);
427 e32(R300_PFS_NODE_LAST_NODE
);
429 R300_STATECHANGE(r300
, fpi
[0]);
430 R300_STATECHANGE(r300
, fpi
[1]);
431 R300_STATECHANGE(r300
, fpi
[2]);
432 R300_STATECHANGE(r300
, fpi
[3]);
434 reg_start(R300_PFS_INSTR0_0
, 0);
435 e32(FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
)));
437 reg_start(R300_PFS_INSTR1_0
, 0);
438 e32(FP_SELC(0,NO
,XYZ
,FP_TMP(0),0,0));
440 reg_start(R300_PFS_INSTR2_0
, 0);
441 e32(FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
)));
443 reg_start(R300_PFS_INSTR3_0
, 0);
444 e32(FP_SELA(0,NO
,W
,FP_TMP(0),0,0));
446 R300_STATECHANGE(r300
, pvs
);
447 reg_start(R300_VAP_PVS_CNTL_1
, 2);
448 e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
449 (0 << R300_PVS_CNTL_1_POS_END_SHIFT
) |
450 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT
));
452 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
454 R300_STATECHANGE(r300
, vpi
);
455 vsf_start_fragment(0x0, 8);
456 e32(VP_OUT(ADD
,OUT
,0,XYZW
));
461 e32(VP_OUT(ADD
,OUT
,1,XYZW
));
472 static void r300Clear(GLcontext
* ctx
, GLbitfield mask
, GLboolean all
,
473 GLint cx
, GLint cy
, GLint cw
, GLint ch
)
475 r300ContextPtr r300
= R300_CONTEXT(ctx
);
476 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
481 if (RADEON_DEBUG
& DEBUG_IOCTL
)
482 fprintf(stderr
, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n",
483 __FUNCTION__
, all
, cx
, cy
, cw
, ch
);
486 LOCK_HARDWARE(&r300
->radeon
);
487 UNLOCK_HARDWARE(&r300
->radeon
);
488 if (dPriv
->numClipRects
== 0)
492 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
493 flags
|= BUFFER_BIT_FRONT_LEFT
;
494 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
497 if (mask
& BUFFER_BIT_BACK_LEFT
) {
498 flags
|= BUFFER_BIT_BACK_LEFT
;
499 mask
&= ~BUFFER_BIT_BACK_LEFT
;
502 if (mask
& BUFFER_BIT_DEPTH
) {
503 bits
|= CLEARBUFFER_DEPTH
;
504 mask
&= ~BUFFER_BIT_DEPTH
;
507 if ( (mask
& BUFFER_BIT_STENCIL
) && r300
->state
.stencil
.hw_stencil
) {
508 bits
|= CLEARBUFFER_STENCIL
;
509 mask
&= ~BUFFER_BIT_STENCIL
;
513 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
514 fprintf(stderr
, "%s: swrast clear, mask: %x\n",
516 _swrast_Clear(ctx
, mask
, all
, cx
, cy
, cw
, ch
);
519 swapped
= r300
->radeon
.doPageFlip
&& (r300
->radeon
.sarea
->pfCurrentPage
== 1);
523 r300EmitClearState(ctx
);
526 if (flags
& BUFFER_BIT_FRONT_LEFT
) {
527 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
);
531 if (flags
& BUFFER_BIT_BACK_LEFT
) {
532 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
^ 1);
537 r300ClearBuffer(r300
, bits
, 0);
540 /* Recalculate the hardware state. This could be done more efficiently,
541 * but do keep it like this for now.
543 r300ResetHwState(r300
);
545 /* r300ClearBuffer has trampled all over the hardware state.. */
546 r300
->hw
.all_dirty
=GL_TRUE
;
550 void r300Flush(GLcontext
* ctx
)
552 r300ContextPtr r300
= R300_CONTEXT(ctx
);
554 if (RADEON_DEBUG
& DEBUG_IOCTL
)
555 fprintf(stderr
, "%s\n", __FUNCTION__
);
557 if (r300
->cmdbuf
.count_used
> r300
->cmdbuf
.count_reemit
)
558 r300FlushCmdBuf(r300
, __FUNCTION__
);
561 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
563 struct r300_dma_buffer
*dmabuf
;
564 int fd
= rmesa
->radeon
.dri
.fd
;
570 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
571 fprintf(stderr
, "%s\n", __FUNCTION__
);
573 if (rmesa
->dma
.flush
) {
574 rmesa
->dma
.flush(rmesa
);
577 if (rmesa
->dma
.current
.buf
)
578 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
580 if (rmesa
->dma
.nr_released_bufs
> 4)
581 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
583 dma
.context
= rmesa
->radeon
.dri
.hwContext
;
585 dma
.send_list
= NULL
;
586 dma
.send_sizes
= NULL
;
588 dma
.request_count
= 1;
589 dma
.request_size
= RADEON_BUFFER_SIZE
;
590 dma
.request_list
= &index
;
591 dma
.request_sizes
= &size
;
592 dma
.granted_count
= 0;
594 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
596 ret
= drmDMA(fd
, &dma
);
599 /* Try to release some buffers and wait until we can't get any more */
600 if (rmesa
->dma
.nr_released_bufs
) {
601 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
604 if (RADEON_DEBUG
& DEBUG_DMA
)
605 fprintf(stderr
, "Waiting for buffers\n");
607 radeonWaitForIdleLocked(&rmesa
->radeon
);
608 ret
= drmDMA(fd
, &dma
);
611 UNLOCK_HARDWARE(&rmesa
->radeon
);
612 fprintf(stderr
, "Error: Could not get dma buffer... exiting\n");
617 UNLOCK_HARDWARE(&rmesa
->radeon
);
619 if (RADEON_DEBUG
& DEBUG_DMA
)
620 fprintf(stderr
, "Allocated buffer %d\n", index
);
622 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
623 dmabuf
->buf
= &rmesa
->radeon
.radeonScreen
->buffers
->list
[index
];
624 dmabuf
->refcount
= 1;
626 rmesa
->dma
.current
.buf
= dmabuf
;
627 rmesa
->dma
.current
.address
= dmabuf
->buf
->address
;
628 rmesa
->dma
.current
.end
= dmabuf
->buf
->total
;
629 rmesa
->dma
.current
.start
= 0;
630 rmesa
->dma
.current
.ptr
= 0;
633 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
634 struct r300_dma_region
*region
, const char *caller
)
636 if (RADEON_DEBUG
& DEBUG_IOCTL
)
637 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
642 if (rmesa
->dma
.flush
)
643 rmesa
->dma
.flush(rmesa
);
645 if (--region
->buf
->refcount
== 0) {
646 drm_radeon_cmd_header_t
*cmd
;
648 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
649 fprintf(stderr
, "%s -- DISCARD BUF %d\n", __FUNCTION__
,
650 region
->buf
->buf
->idx
);
652 (drm_radeon_cmd_header_t
*) r300AllocCmdBuf(rmesa
,
655 cmd
->dma
.cmd_type
= R300_CMD_DMA_DISCARD
;
656 cmd
->dma
.buf_idx
= region
->buf
->buf
->idx
;
659 rmesa
->dma
.nr_released_bufs
++;
666 /* Allocates a region from rmesa->dma.current. If there isn't enough
667 * space in current, grab a new buffer (and discard what was left of current)
669 void r300AllocDmaRegion(r300ContextPtr rmesa
,
670 struct r300_dma_region
*region
,
671 int bytes
, int alignment
)
673 if (RADEON_DEBUG
& DEBUG_IOCTL
)
674 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
676 if (rmesa
->dma
.flush
)
677 rmesa
->dma
.flush(rmesa
);
680 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
683 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
684 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
686 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
687 r300RefillCurrentDmaRegion(rmesa
);
689 region
->start
= rmesa
->dma
.current
.start
;
690 region
->ptr
= rmesa
->dma
.current
.start
;
691 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
692 region
->address
= rmesa
->dma
.current
.address
;
693 region
->buf
= rmesa
->dma
.current
.buf
;
694 region
->buf
->refcount
++;
696 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
697 rmesa
->dma
.current
.start
=
698 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
700 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
703 /* Called via glXGetMemoryOffsetMESA() */
704 GLuint
r300GetMemoryOffsetMESA(__DRInativeDisplay
* dpy
, int scrn
,
705 const GLvoid
* pointer
)
707 GET_CURRENT_CONTEXT(ctx
);
708 r300ContextPtr rmesa
;
711 if (!ctx
|| !(rmesa
= R300_CONTEXT(ctx
))) {
712 fprintf(stderr
, "%s: no context\n", __FUNCTION__
);
716 if (!r300IsGartMemory(rmesa
, pointer
, 0))
719 if (rmesa
->radeon
.dri
.drmMinor
< 6)
722 card_offset
= r300GartOffsetFromVirtual(rmesa
, pointer
);
724 return card_offset
- rmesa
->radeon
.radeonScreen
->gart_base
;
727 GLboolean
r300IsGartMemory(r300ContextPtr rmesa
, const GLvoid
* pointer
,
731 (char *)pointer
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
732 int valid
= (size
>= 0 && offset
>= 0
733 && offset
+ size
< rmesa
->radeon
.radeonScreen
->gartTextures
.size
);
735 if (RADEON_DEBUG
& DEBUG_IOCTL
)
736 fprintf(stderr
, "r300IsGartMemory( %p ) : %d\n", pointer
,
742 GLuint
r300GartOffsetFromVirtual(r300ContextPtr rmesa
, const GLvoid
* pointer
)
745 (char *)pointer
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
747 //fprintf(stderr, "offset=%08x\n", offset);
749 if (offset
< 0 || offset
> rmesa
->radeon
.radeonScreen
->gartTextures
.size
)
752 return rmesa
->radeon
.radeonScreen
->gart_texture_offset
+ offset
;
755 void r300InitIoctlFuncs(struct dd_function_table
*functions
)
757 functions
->Clear
= r300Clear
;
758 functions
->Finish
= radeonFinish
;
759 functions
->Flush
= r300Flush
;