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"
58 #define CLEARBUFFER_COLOR 0x1
59 #define CLEARBUFFER_DEPTH 0x2
60 #define CLEARBUFFER_STENCIL 0x4
62 static void r300ClearBuffer(r300ContextPtr r300
, int flags
, int buffer
)
64 GLcontext
* ctx
= r300
->radeon
.glCtx
;
65 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
66 GLuint cboffset
, cbpitch
;
67 drm_r300_cmd_header_t
* cmd2
;
69 r300ContextPtr rmesa
=r300
;
72 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
)->packet0
.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
)->packet0
.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 if (r300
->radeon
.radeonScreen
->cpp
== 4)
129 cbpitch
|= R300_COLOR_FORMAT_ARGB8888
;
131 cbpitch
|= R300_COLOR_FORMAT_RGB565
;
133 if (r300
->radeon
.sarea
->tiling_enabled
)
134 cbpitch
|= R300_COLOR_TILE_ENABLE
;
136 R300_STATECHANGE(r300
, cb
);
137 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = cboffset
;
138 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = cbpitch
;
140 R300_STATECHANGE(r300
, unk221C
);
141 r300
->hw
.unk221C
.cmd
[1] = R300_221C_CLEAR
;
143 R300_STATECHANGE(r300
, ps
);
144 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
145 ((dPriv
->w
* 6) << R300_POINTSIZE_X_SHIFT
) |
146 ((dPriv
->h
* 6) << R300_POINTSIZE_Y_SHIFT
);
148 R300_STATECHANGE(r300
, ri
);
149 for(i
= 1; i
<= 8; ++i
)
150 r300
->hw
.ri
.cmd
[i
] = R300_RS_INTERP_USED
;
152 R300_STATECHANGE(r300
, rc
);
153 /* The second constant is needed to get glxgears display anything .. */
154 r300
->hw
.rc
.cmd
[1] = (1 << R300_RS_CNTL_CI_CNT_SHIFT
) | R300_RS_CNTL_0_UNKNOWN_18
;
155 r300
->hw
.rc
.cmd
[2] = 0;
157 R300_STATECHANGE(r300
, rr
);
158 ((drm_r300_cmd_header_t
*)r300
->hw
.rr
.cmd
)->packet0
.count
= 1;
159 r300
->hw
.rr
.cmd
[1] = 0x00004000;
161 R300_STATECHANGE(r300
, cmk
);
162 if (flags
& CLEARBUFFER_COLOR
) {
163 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] =
164 (ctx
->Color
.ColorMask
[BCOMP
] ? R300_COLORMASK0_B
: 0) |
165 (ctx
->Color
.ColorMask
[GCOMP
] ? R300_COLORMASK0_G
: 0) |
166 (ctx
->Color
.ColorMask
[RCOMP
] ? R300_COLORMASK0_R
: 0) |
167 (ctx
->Color
.ColorMask
[ACOMP
] ? R300_COLORMASK0_A
: 0);
169 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = 0;
172 R300_STATECHANGE(r300
, fp
);
173 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0; /* 1 pass, no textures */
174 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0; /* no temporaries */
175 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0; /* no offset, one ALU instr */
176 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
177 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
178 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
179 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = R300_PFS_NODE_OUTPUT_COLOR
;
181 R300_STATECHANGE(r300
, fpi
[0]);
182 R300_STATECHANGE(r300
, fpi
[1]);
183 R300_STATECHANGE(r300
, fpi
[2]);
184 R300_STATECHANGE(r300
, fpi
[3]);
185 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[0].cmd
)->packet0
.count
= 1;
186 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[1].cmd
)->packet0
.count
= 1;
187 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[2].cmd
)->packet0
.count
= 1;
188 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[3].cmd
)->packet0
.count
= 1;
191 r300
->hw
.fpi
[0].cmd
[1] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
192 r300
->hw
.fpi
[1].cmd
[1] = FP_SELC(0,NO
,XYZ
,FP_TMP(0),0,0);
193 r300
->hw
.fpi
[2].cmd
[1] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
194 r300
->hw
.fpi
[3].cmd
[1] = FP_SELA(0,NO
,W
,FP_TMP(0),0,0);
196 R300_STATECHANGE(r300
, pvs
);
197 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
198 (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
199 (0 << R300_PVS_CNTL_1_POS_END_SHIFT
) |
200 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
201 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0; /* no parameters */
202 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
203 (1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
205 R300_STATECHANGE(r300
, vpi
);
206 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->packet0
.count
= 8;
209 r300
->hw
.vpi
.cmd
[1] = VP_OUT(ADD
,OUT
,0,XYZW
);
210 r300
->hw
.vpi
.cmd
[2] = VP_IN(IN
,0);
211 r300
->hw
.vpi
.cmd
[3] = VP_ZERO();
212 r300
->hw
.vpi
.cmd
[4] = 0;
215 r300
->hw
.vpi
.cmd
[5] = VP_OUT(ADD
,OUT
,1,XYZW
);
216 r300
->hw
.vpi
.cmd
[6] = VP_IN(IN
,1);
217 r300
->hw
.vpi
.cmd
[7] = VP_ZERO();
218 r300
->hw
.vpi
.cmd
[8] = 0;
220 R300_STATECHANGE(r300
, zs
);
221 if (flags
& CLEARBUFFER_DEPTH
) {
222 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
223 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= 0x6; // test and write
224 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
225 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
227 R300_STATECHANGE(r300, zb);
228 r300->hw.zb.cmd[R300_ZB_OFFSET] =
230 r300->radeon.radeonScreen->frontOffset +
231 r300->radeon.radeonScreen->fbLocation;
232 r300->hw.zb.cmd[R300_ZB_PITCH] =
233 r300->radeon.radeonScreen->depthPitch;
236 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
237 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_DISABLED_1
; // disable
238 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
241 R300_STATECHANGE(r300
, zs
);
242 if (flags
& CLEARBUFFER_STENCIL
) {
243 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= ~R300_RB3D_STENCIL_ENABLE
;
244 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_STENCIL_ENABLE
;
245 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
246 ~((R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
247 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
248 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
249 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
250 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
251 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
252 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
253 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
254 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
255 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
) ;
256 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] = r300
->state
.stencil
.clear
;
259 /* Make sure we have enough space */
260 r300EnsureCmdBufSpace(r300
, r300
->hw
.max_state_size
+ 9+8, __FUNCTION__
);
265 cp_wait(r300
, R300_WAIT_3D
| R300_WAIT_3D_CLEAN
);
266 end_3d(PASS_PREFIX_VOID
);
269 R300_STATECHANGE(r300
, cb
);
270 reg_start(R300_RB3D_COLOROFFSET0
, 0);
273 if (r300
->radeon
.radeonScreen
->cpp
== 4)
274 cbpitch
|= R300_COLOR_FORMAT_ARGB8888
;
276 cbpitch
|= R300_COLOR_FORMAT_RGB565
;
278 if (r300
->radeon
.sarea
->tiling_enabled
)
279 cbpitch
|= R300_COLOR_TILE_ENABLE
;
281 reg_start(R300_RB3D_COLORPITCH0
, 0);
284 R300_STATECHANGE(r300
, cmk
);
285 reg_start(R300_RB3D_COLORMASK
, 0);
287 if (flags
& CLEARBUFFER_COLOR
) {
288 e32((ctx
->Color
.ColorMask
[BCOMP
] ? R300_COLORMASK0_B
: 0) |
289 (ctx
->Color
.ColorMask
[GCOMP
] ? R300_COLORMASK0_G
: 0) |
290 (ctx
->Color
.ColorMask
[RCOMP
] ? R300_COLORMASK0_R
: 0) |
291 (ctx
->Color
.ColorMask
[ACOMP
] ? R300_COLORMASK0_A
: 0));
296 R300_STATECHANGE(r300
, zs
);
297 reg_start(R300_RB3D_ZSTENCIL_CNTL_0
, 2);
302 t1
= r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
];
303 t2
= r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
];
305 if (flags
& CLEARBUFFER_DEPTH
) {
306 t1
&= R300_RB3D_STENCIL_ENABLE
;
307 t1
|= 0x6; // test and write
309 t2
&= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
310 t2
|= (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
312 R300_STATECHANGE(r300, zb);
313 r300->hw.zb.cmd[R300_ZB_OFFSET] =
315 r300->radeon.radeonScreen->frontOffset +
316 r300->radeon.radeonScreen->fbLocation;
317 r300->hw.zb.cmd[R300_ZB_PITCH] =
318 r300->radeon.radeonScreen->depthPitch;
321 t1
&= R300_RB3D_STENCIL_ENABLE
;
322 t1
|= R300_RB3D_Z_DISABLED_1
; // disable
324 t2
&= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
327 if (flags
& CLEARBUFFER_STENCIL
) {
328 t1
&= ~R300_RB3D_STENCIL_ENABLE
;
329 t1
|= R300_RB3D_STENCIL_ENABLE
;
332 ~((R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
334 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
335 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
336 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
337 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
338 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
339 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
340 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
341 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
) ;
346 e32(r300
->state
.stencil
.clear
);
351 cmd2
= (drm_r300_cmd_header_t
*)r300AllocCmdBuf(r300
, 9, __FUNCTION__
);
352 cmd2
[0].packet3
.cmd_type
= R300_CMD_PACKET3
;
353 cmd2
[0].packet3
.packet
= R300_CMD_PACKET3_CLEAR
;
354 cmd2
[1].u
= r300PackFloat32(dPriv
->w
/ 2.0);
355 cmd2
[2].u
= r300PackFloat32(dPriv
->h
/ 2.0);
356 cmd2
[3].u
= r300PackFloat32(ctx
->Depth
.Clear
);
357 cmd2
[4].u
= r300PackFloat32(1.0);
358 cmd2
[5].u
= r300PackFloat32(ctx
->Color
.ClearColor
[0]);
359 cmd2
[6].u
= r300PackFloat32(ctx
->Color
.ClearColor
[1]);
360 cmd2
[7].u
= r300PackFloat32(ctx
->Color
.ClearColor
[2]);
361 cmd2
[8].u
= r300PackFloat32(ctx
->Color
.ClearColor
[3]);
364 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
370 cp_wait(rmesa
, R300_WAIT_3D
| R300_WAIT_3D_CLEAN
);
375 static void r300EmitClearState(GLcontext
* ctx
)
377 r300ContextPtr r300
= R300_CONTEXT(ctx
);
378 r300ContextPtr rmesa
=r300
;
379 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
383 R300_STATECHANGE(r300
, vir
[0]);
384 reg_start(R300_VAP_INPUT_ROUTE_0_0
, 0);
387 R300_STATECHANGE(r300
, vir
[1]);
388 reg_start(R300_VAP_INPUT_ROUTE_1_0
, 0);
391 R300_STATECHANGE(r300
, vic
);
392 reg_start(R300_VAP_INPUT_CNTL_0
, 1);
396 R300_STATECHANGE(r300
, vof
);
397 reg_start(R300_VAP_OUTPUT_VTX_FMT_0
, 1);
398 e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
);
399 e32(0); /* no textures */
402 R300_STATECHANGE(r300
, txe
);
403 reg_start(R300_TX_ENABLE
, 0);
406 R300_STATECHANGE(r300
, vpt
);
407 reg_start(R300_SE_VPORT_XSCALE
, 5);
415 R300_STATECHANGE(r300
, at
);
416 reg_start(R300_PP_ALPHA_TEST
, 0);
419 R300_STATECHANGE(r300
, bld
);
420 reg_start(R300_RB3D_CBLEND
, 1);
424 R300_STATECHANGE(r300
, unk221C
);
425 reg_start(0x221C, 0);
426 e32(R300_221C_CLEAR
);
428 R300_STATECHANGE(r300
, ps
);
429 reg_start(R300_RE_POINTSIZE
, 0);
430 e32(((dPriv
->w
* 6) << R300_POINTSIZE_X_SHIFT
) |
431 ((dPriv
->h
* 6) << R300_POINTSIZE_Y_SHIFT
));
433 R300_STATECHANGE(r300
, ri
);
434 reg_start(R300_RS_INTERP_0
, 8);
435 for(i
= 0; i
< 8; ++i
){
436 e32(R300_RS_INTERP_USED
);
439 R300_STATECHANGE(r300
, rc
);
440 /* The second constant is needed to get glxgears display anything .. */
441 reg_start(R300_RS_CNTL_0
, 1);
442 e32((1 << R300_RS_CNTL_CI_CNT_SHIFT
) | R300_RS_CNTL_0_UNKNOWN_18
);
445 R300_STATECHANGE(r300
, rr
);
446 reg_start(R300_RS_ROUTE_0
, 0);
449 R300_STATECHANGE(r300
, fp
);
450 reg_start(R300_PFS_CNTL_0
, 2);
454 reg_start(R300_PFS_NODE_0
, 3);
458 e32(R300_PFS_NODE_OUTPUT_COLOR
);
460 R300_STATECHANGE(r300
, fpi
[0]);
461 R300_STATECHANGE(r300
, fpi
[1]);
462 R300_STATECHANGE(r300
, fpi
[2]);
463 R300_STATECHANGE(r300
, fpi
[3]);
465 reg_start(R300_PFS_INSTR0_0
, 0);
466 e32(FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
)));
468 reg_start(R300_PFS_INSTR1_0
, 0);
469 e32(FP_SELC(0,NO
,XYZ
,FP_TMP(0),0,0));
471 reg_start(R300_PFS_INSTR2_0
, 0);
472 e32(FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
)));
474 reg_start(R300_PFS_INSTR3_0
, 0);
475 e32(FP_SELA(0,NO
,W
,FP_TMP(0),0,0));
477 R300_STATECHANGE(r300
, pvs
);
478 reg_start(R300_VAP_PVS_CNTL_1
, 2);
479 e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
480 (0 << R300_PVS_CNTL_1_POS_END_SHIFT
) |
481 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT
));
483 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
485 R300_STATECHANGE(r300
, vpi
);
486 vsf_start_fragment(0x0, 8);
487 e32(VP_OUT(ADD
,OUT
,0,XYZW
));
492 e32(VP_OUT(ADD
,OUT
,1,XYZW
));
497 /*reg_start(0x4500,0);
505 static void r300Clear(GLcontext
* ctx
, GLbitfield mask
, GLboolean all
,
506 GLint cx
, GLint cy
, GLint cw
, GLint ch
)
508 r300ContextPtr r300
= R300_CONTEXT(ctx
);
509 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
514 if (RADEON_DEBUG
& DEBUG_IOCTL
)
515 fprintf(stderr
, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n",
516 __FUNCTION__
, all
, cx
, cy
, cw
, ch
);
519 LOCK_HARDWARE(&r300
->radeon
);
520 UNLOCK_HARDWARE(&r300
->radeon
);
521 if (dPriv
->numClipRects
== 0)
525 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
526 flags
|= BUFFER_BIT_FRONT_LEFT
;
527 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
530 if (mask
& BUFFER_BIT_BACK_LEFT
) {
531 flags
|= BUFFER_BIT_BACK_LEFT
;
532 mask
&= ~BUFFER_BIT_BACK_LEFT
;
535 if (mask
& BUFFER_BIT_DEPTH
) {
536 bits
|= CLEARBUFFER_DEPTH
;
537 mask
&= ~BUFFER_BIT_DEPTH
;
540 if ( (mask
& BUFFER_BIT_STENCIL
) && r300
->state
.stencil
.hw_stencil
) {
541 bits
|= CLEARBUFFER_STENCIL
;
542 mask
&= ~BUFFER_BIT_STENCIL
;
546 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
547 fprintf(stderr
, "%s: swrast clear, mask: %x\n",
549 _swrast_Clear(ctx
, mask
, all
, cx
, cy
, cw
, ch
);
552 swapped
= r300
->radeon
.doPageFlip
&& (r300
->radeon
.sarea
->pfCurrentPage
== 1);
555 WARN_ONCE("CB_DPATH has been enabled.\nPlease let me know if this introduces new instabilities.\n");
556 /* Make sure it fits there. */
557 r300EnsureCmdBufSpace(r300
, 419*3, __FUNCTION__
);
559 r300EmitClearState(ctx
);
562 if (flags
& BUFFER_BIT_FRONT_LEFT
) {
563 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
);
567 if (flags
& BUFFER_BIT_BACK_LEFT
) {
568 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
^ 1);
573 r300ClearBuffer(r300
, bits
, 0);
576 /* Recalculate the hardware state. This could be done more efficiently,
577 * but do keep it like this for now.
579 r300ResetHwState(r300
);
581 /* r300ClearBuffer has trampled all over the hardware state.. */
582 r300
->hw
.all_dirty
=GL_TRUE
;
587 void r300Flush(GLcontext
* ctx
)
589 r300ContextPtr r300
= R300_CONTEXT(ctx
);
591 if (RADEON_DEBUG
& DEBUG_IOCTL
)
592 fprintf(stderr
, "%s\n", __FUNCTION__
);
594 if (r300
->cmdbuf
.count_used
> r300
->cmdbuf
.count_reemit
)
595 r300FlushCmdBuf(r300
, __FUNCTION__
);
599 #include "radeon_mm.h"
601 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
603 struct r300_dma_buffer
*dmabuf
;
604 int fd
= rmesa
->radeon
.dri
.fd
;
610 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
611 fprintf(stderr
, "%s\n", __FUNCTION__
);
613 if (rmesa
->dma
.flush
) {
614 rmesa
->dma
.flush(rmesa
);
617 if (rmesa
->dma
.current
.buf
)
618 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
620 if (rmesa
->dma
.nr_released_bufs
> 4)
621 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
623 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
624 dmabuf
->buf
= (void *)1; /* hack */
625 dmabuf
->refcount
= 1;
627 dmabuf
->id
= radeon_mm_alloc(rmesa
, 4, RADEON_BUFFER_SIZE
*16);
629 rmesa
->dma
.current
.buf
= dmabuf
;
630 rmesa
->dma
.current
.address
= radeon_mm_ptr(rmesa
, dmabuf
->id
);
631 rmesa
->dma
.current
.end
= RADEON_BUFFER_SIZE
*16;
632 rmesa
->dma
.current
.start
= 0;
633 rmesa
->dma
.current
.ptr
= 0;
636 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
637 struct r300_dma_region
*region
, const char *caller
)
639 if (RADEON_DEBUG
& DEBUG_IOCTL
)
640 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
645 if (rmesa
->dma
.flush
)
646 rmesa
->dma
.flush(rmesa
);
648 if (--region
->buf
->refcount
== 0) {
649 radeon_mm_free(rmesa
, region
->buf
->id
);
651 rmesa
->dma
.nr_released_bufs
++;
658 /* Allocates a region from rmesa->dma.current. If there isn't enough
659 * space in current, grab a new buffer (and discard what was left of current)
661 void r300AllocDmaRegion(r300ContextPtr rmesa
,
662 struct r300_dma_region
*region
,
663 int bytes
, int alignment
)
665 if (RADEON_DEBUG
& DEBUG_IOCTL
)
666 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
668 if (rmesa
->dma
.flush
)
669 rmesa
->dma
.flush(rmesa
);
672 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
675 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
676 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
678 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
679 r300RefillCurrentDmaRegion(rmesa
);
681 region
->start
= rmesa
->dma
.current
.start
;
682 region
->ptr
= rmesa
->dma
.current
.start
;
683 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
684 region
->address
= rmesa
->dma
.current
.address
;
685 region
->buf
= rmesa
->dma
.current
.buf
;
686 region
->buf
->refcount
++;
688 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
689 rmesa
->dma
.current
.start
=
690 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
692 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
696 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
698 struct r300_dma_buffer
*dmabuf
;
699 int fd
= rmesa
->radeon
.dri
.fd
;
705 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
706 fprintf(stderr
, "%s\n", __FUNCTION__
);
708 if (rmesa
->dma
.flush
) {
709 rmesa
->dma
.flush(rmesa
);
712 if (rmesa
->dma
.current
.buf
)
713 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
715 if (rmesa
->dma
.nr_released_bufs
> 4)
716 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
718 dma
.context
= rmesa
->radeon
.dri
.hwContext
;
720 dma
.send_list
= NULL
;
721 dma
.send_sizes
= NULL
;
723 dma
.request_count
= 1;
724 dma
.request_size
= RADEON_BUFFER_SIZE
;
725 dma
.request_list
= &index
;
726 dma
.request_sizes
= &size
;
727 dma
.granted_count
= 0;
729 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
731 ret
= drmDMA(fd
, &dma
);
734 /* Try to release some buffers and wait until we can't get any more */
735 if (rmesa
->dma
.nr_released_bufs
) {
736 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
739 if (RADEON_DEBUG
& DEBUG_DMA
)
740 fprintf(stderr
, "Waiting for buffers\n");
742 radeonWaitForIdleLocked(&rmesa
->radeon
);
743 ret
= drmDMA(fd
, &dma
);
746 UNLOCK_HARDWARE(&rmesa
->radeon
);
747 fprintf(stderr
, "Error: Could not get dma buffer... exiting\n");
752 UNLOCK_HARDWARE(&rmesa
->radeon
);
754 if (RADEON_DEBUG
& DEBUG_DMA
)
755 fprintf(stderr
, "Allocated buffer %d\n", index
);
757 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
758 dmabuf
->buf
= &rmesa
->radeon
.radeonScreen
->buffers
->list
[index
];
759 dmabuf
->refcount
= 1;
761 rmesa
->dma
.current
.buf
= dmabuf
;
762 rmesa
->dma
.current
.address
= dmabuf
->buf
->address
;
763 rmesa
->dma
.current
.end
= dmabuf
->buf
->total
;
764 rmesa
->dma
.current
.start
= 0;
765 rmesa
->dma
.current
.ptr
= 0;
768 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
769 struct r300_dma_region
*region
, const char *caller
)
771 if (RADEON_DEBUG
& DEBUG_IOCTL
)
772 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
777 if (rmesa
->dma
.flush
)
778 rmesa
->dma
.flush(rmesa
);
780 if (--region
->buf
->refcount
== 0) {
781 drm_radeon_cmd_header_t
*cmd
;
783 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
784 fprintf(stderr
, "%s -- DISCARD BUF %d\n", __FUNCTION__
,
785 region
->buf
->buf
->idx
);
787 (drm_radeon_cmd_header_t
*) r300AllocCmdBuf(rmesa
,
790 cmd
->dma
.cmd_type
= R300_CMD_DMA_DISCARD
;
791 cmd
->dma
.buf_idx
= region
->buf
->buf
->idx
;
794 rmesa
->dma
.nr_released_bufs
++;
801 /* Allocates a region from rmesa->dma.current. If there isn't enough
802 * space in current, grab a new buffer (and discard what was left of current)
804 void r300AllocDmaRegion(r300ContextPtr rmesa
,
805 struct r300_dma_region
*region
,
806 int bytes
, int alignment
)
808 if (RADEON_DEBUG
& DEBUG_IOCTL
)
809 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
811 if (rmesa
->dma
.flush
)
812 rmesa
->dma
.flush(rmesa
);
815 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
818 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
819 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
821 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
822 r300RefillCurrentDmaRegion(rmesa
);
824 region
->start
= rmesa
->dma
.current
.start
;
825 region
->ptr
= rmesa
->dma
.current
.start
;
826 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
827 region
->address
= rmesa
->dma
.current
.address
;
828 region
->buf
= rmesa
->dma
.current
.buf
;
829 region
->buf
->refcount
++;
831 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
832 rmesa
->dma
.current
.start
=
833 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
835 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
840 /* Called via glXGetMemoryOffsetMESA() */
841 GLuint
r300GetMemoryOffsetMESA(__DRInativeDisplay
* dpy
, int scrn
,
842 const GLvoid
* pointer
)
844 GET_CURRENT_CONTEXT(ctx
);
845 r300ContextPtr rmesa
;
848 if (!ctx
|| !(rmesa
= R300_CONTEXT(ctx
))) {
849 fprintf(stderr
, "%s: no context\n", __FUNCTION__
);
853 if (!r300IsGartMemory(rmesa
, pointer
, 0))
856 if (rmesa
->radeon
.dri
.drmMinor
< 6)
859 card_offset
= r300GartOffsetFromVirtual(rmesa
, pointer
);
861 return card_offset
- rmesa
->radeon
.radeonScreen
->gart_base
;
864 GLboolean
r300IsGartMemory(r300ContextPtr rmesa
, const GLvoid
* pointer
,
868 (char *)pointer
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
869 int valid
= (size
>= 0 && offset
>= 0
870 && offset
+ size
< rmesa
->radeon
.radeonScreen
->gartTextures
.size
);
872 if (RADEON_DEBUG
& DEBUG_IOCTL
)
873 fprintf(stderr
, "r300IsGartMemory( %p ) : %d\n", pointer
,
879 GLuint
r300GartOffsetFromVirtual(r300ContextPtr rmesa
, const GLvoid
* pointer
)
882 (char *)pointer
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
884 //fprintf(stderr, "offset=%08x\n", offset);
886 if (offset
< 0 || offset
> rmesa
->radeon
.radeonScreen
->gartTextures
.size
)
889 return rmesa
->radeon
.radeonScreen
->gart_texture_offset
+ offset
;
892 void r300InitIoctlFuncs(struct dd_function_table
*functions
)
894 functions
->Clear
= r300Clear
;
895 functions
->Finish
= radeonFinish
;
896 functions
->Flush
= r300Flush
;