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 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
)->unchecked_state
.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_LAST_NODE
;
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
)->unchecked_state
.count
= 1;
186 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[1].cmd
)->unchecked_state
.count
= 1;
187 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[2].cmd
)->unchecked_state
.count
= 1;
188 ((drm_r300_cmd_header_t
*)r300
->hw
.fpi
[3].cmd
)->unchecked_state
.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
)->unchecked_state
.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__
);
264 R300_STATECHANGE(r300
, cb
);
265 reg_start(R300_RB3D_COLOROFFSET0
, 0);
268 if (r300
->radeon
.radeonScreen
->cpp
== 4)
269 cbpitch
|= R300_COLOR_FORMAT_ARGB8888
;
271 cbpitch
|= R300_COLOR_FORMAT_RGB565
;
273 reg_start(R300_RB3D_COLORPITCH0
, 0);
276 R300_STATECHANGE(r300
, cmk
);
277 reg_start(R300_RB3D_COLORMASK
, 0);
279 if (flags
& CLEARBUFFER_COLOR
) {
280 e32((ctx
->Color
.ColorMask
[BCOMP
] ? R300_COLORMASK0_B
: 0) |
281 (ctx
->Color
.ColorMask
[GCOMP
] ? R300_COLORMASK0_G
: 0) |
282 (ctx
->Color
.ColorMask
[RCOMP
] ? R300_COLORMASK0_R
: 0) |
283 (ctx
->Color
.ColorMask
[ACOMP
] ? R300_COLORMASK0_A
: 0));
288 R300_STATECHANGE(r300
, zs
);
289 reg_start(R300_RB3D_ZSTENCIL_CNTL_0
, 2);
294 t1
= r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
];
295 t2
= r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
];
297 if (flags
& CLEARBUFFER_DEPTH
) {
298 t1
&= R300_RB3D_STENCIL_ENABLE
;
299 t1
|= 0x6; // test and write
301 t2
&= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
302 t2
|= (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
304 R300_STATECHANGE(r300, zb);
305 r300->hw.zb.cmd[R300_ZB_OFFSET] =
307 r300->radeon.radeonScreen->frontOffset +
308 r300->radeon.radeonScreen->fbLocation;
309 r300->hw.zb.cmd[R300_ZB_PITCH] =
310 r300->radeon.radeonScreen->depthPitch;
313 t1
&= R300_RB3D_STENCIL_ENABLE
;
314 t1
|= R300_RB3D_Z_DISABLED_1
; // disable
316 t2
&= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
319 if (flags
& CLEARBUFFER_STENCIL
) {
320 t1
&= ~R300_RB3D_STENCIL_ENABLE
;
321 t1
|= R300_RB3D_STENCIL_ENABLE
;
324 ~((R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
326 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
327 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
328 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
329 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
330 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
331 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
332 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
333 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
) ;
338 e32(r300
->state
.stencil
.clear
);
343 cmd2
= (drm_r300_cmd_header_t
*)r300AllocCmdBuf(r300
, 9, __FUNCTION__
);
344 cmd2
[0].packet3
.cmd_type
= R300_CMD_PACKET3
;
345 cmd2
[0].packet3
.packet
= R300_CMD_PACKET3_CLEAR
;
346 cmd2
[1].u
= r300PackFloat32(dPriv
->w
/ 2.0);
347 cmd2
[2].u
= r300PackFloat32(dPriv
->h
/ 2.0);
348 cmd2
[3].u
= r300PackFloat32(ctx
->Depth
.Clear
);
349 cmd2
[4].u
= r300PackFloat32(1.0);
350 cmd2
[5].u
= r300PackFloat32(ctx
->Color
.ClearColor
[0]);
351 cmd2
[6].u
= r300PackFloat32(ctx
->Color
.ClearColor
[1]);
352 cmd2
[7].u
= r300PackFloat32(ctx
->Color
.ClearColor
[2]);
353 cmd2
[8].u
= r300PackFloat32(ctx
->Color
.ClearColor
[3]);
357 static void r300EmitClearState(GLcontext
* ctx
)
359 r300ContextPtr r300
= R300_CONTEXT(ctx
);
360 r300ContextPtr rmesa
=r300
;
361 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
365 R300_STATECHANGE(r300
, vir
[0]);
366 reg_start(R300_VAP_INPUT_ROUTE_0_0
, 0);
369 R300_STATECHANGE(r300
, vir
[1]);
370 reg_start(R300_VAP_INPUT_ROUTE_1_0
, 0);
373 R300_STATECHANGE(r300
, vic
);
374 reg_start(R300_VAP_INPUT_CNTL_0
, 1);
378 R300_STATECHANGE(r300
, vof
);
379 reg_start(R300_VAP_OUTPUT_VTX_FMT_0
, 1);
380 e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
);
381 e32(0); /* no textures */
384 R300_STATECHANGE(r300
, txe
);
385 reg_start(R300_TX_ENABLE
, 0);
388 R300_STATECHANGE(r300
, vpt
);
389 reg_start(R300_SE_VPORT_XSCALE
, 5);
397 R300_STATECHANGE(r300
, at
);
398 reg_start(R300_PP_ALPHA_TEST
, 0);
401 R300_STATECHANGE(r300
, bld
);
402 reg_start(R300_RB3D_CBLEND
, 1);
406 R300_STATECHANGE(r300
, unk221C
);
407 reg_start(0x221C, 0);
408 e32(R300_221C_CLEAR
);
410 R300_STATECHANGE(r300
, ps
);
411 reg_start(R300_RE_POINTSIZE
, 0);
412 e32(((dPriv
->w
* 6) << R300_POINTSIZE_X_SHIFT
) |
413 ((dPriv
->h
* 6) << R300_POINTSIZE_Y_SHIFT
));
415 R300_STATECHANGE(r300
, ri
);
416 reg_start(R300_RS_INTERP_0
, 8);
417 for(i
= 0; i
< 8; ++i
){
418 e32(R300_RS_INTERP_USED
);
421 R300_STATECHANGE(r300
, rc
);
422 /* The second constant is needed to get glxgears display anything .. */
423 reg_start(R300_RS_CNTL_0
, 1);
424 e32(R300_RS_CNTL_0_UNKNOWN_7
| R300_RS_CNTL_0_UNKNOWN_18
);
427 R300_STATECHANGE(r300
, rr
);
428 reg_start(R300_RS_ROUTE_0
, 0);
431 R300_STATECHANGE(r300
, fp
);
432 reg_start(R300_PFS_CNTL_0
, 2);
436 reg_start(R300_PFS_NODE_0
, 3);
440 e32(R300_PFS_NODE_LAST_NODE
);
442 R300_STATECHANGE(r300
, fpi
[0]);
443 R300_STATECHANGE(r300
, fpi
[1]);
444 R300_STATECHANGE(r300
, fpi
[2]);
445 R300_STATECHANGE(r300
, fpi
[3]);
447 reg_start(R300_PFS_INSTR0_0
, 0);
448 e32(FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
)));
450 reg_start(R300_PFS_INSTR1_0
, 0);
451 e32(FP_SELC(0,NO
,XYZ
,FP_TMP(0),0,0));
453 reg_start(R300_PFS_INSTR2_0
, 0);
454 e32(FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
)));
456 reg_start(R300_PFS_INSTR3_0
, 0);
457 e32(FP_SELA(0,NO
,W
,FP_TMP(0),0,0));
459 R300_STATECHANGE(r300
, pvs
);
460 reg_start(R300_VAP_PVS_CNTL_1
, 2);
461 e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
462 (0 << R300_PVS_CNTL_1_POS_END_SHIFT
) |
463 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT
));
465 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
467 R300_STATECHANGE(r300
, vpi
);
468 vsf_start_fragment(0x0, 8);
469 e32(VP_OUT(ADD
,OUT
,0,XYZW
));
474 e32(VP_OUT(ADD
,OUT
,1,XYZW
));
485 static void r300Clear(GLcontext
* ctx
, GLbitfield mask
, GLboolean all
,
486 GLint cx
, GLint cy
, GLint cw
, GLint ch
)
488 r300ContextPtr r300
= R300_CONTEXT(ctx
);
489 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
494 if (RADEON_DEBUG
& DEBUG_IOCTL
)
495 fprintf(stderr
, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n",
496 __FUNCTION__
, all
, cx
, cy
, cw
, ch
);
499 LOCK_HARDWARE(&r300
->radeon
);
500 UNLOCK_HARDWARE(&r300
->radeon
);
501 if (dPriv
->numClipRects
== 0)
505 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
506 flags
|= BUFFER_BIT_FRONT_LEFT
;
507 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
510 if (mask
& BUFFER_BIT_BACK_LEFT
) {
511 flags
|= BUFFER_BIT_BACK_LEFT
;
512 mask
&= ~BUFFER_BIT_BACK_LEFT
;
515 if (mask
& BUFFER_BIT_DEPTH
) {
516 bits
|= CLEARBUFFER_DEPTH
;
517 mask
&= ~BUFFER_BIT_DEPTH
;
520 if ( (mask
& BUFFER_BIT_STENCIL
) && r300
->state
.stencil
.hw_stencil
) {
521 bits
|= CLEARBUFFER_STENCIL
;
522 mask
&= ~BUFFER_BIT_STENCIL
;
526 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
527 fprintf(stderr
, "%s: swrast clear, mask: %x\n",
529 _swrast_Clear(ctx
, mask
, all
, cx
, cy
, cw
, ch
);
532 swapped
= r300
->radeon
.doPageFlip
&& (r300
->radeon
.sarea
->pfCurrentPage
== 1);
536 r300EmitClearState(ctx
);
539 if (flags
& BUFFER_BIT_FRONT_LEFT
) {
540 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
);
544 if (flags
& BUFFER_BIT_BACK_LEFT
) {
545 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
^ 1);
550 r300ClearBuffer(r300
, bits
, 0);
553 /* Recalculate the hardware state. This could be done more efficiently,
554 * but do keep it like this for now.
556 r300ResetHwState(r300
);
558 /* r300ClearBuffer has trampled all over the hardware state.. */
559 r300
->hw
.all_dirty
=GL_TRUE
;
563 void r300Flush(GLcontext
* ctx
)
565 r300ContextPtr r300
= R300_CONTEXT(ctx
);
567 if (RADEON_DEBUG
& DEBUG_IOCTL
)
568 fprintf(stderr
, "%s\n", __FUNCTION__
);
570 if (r300
->cmdbuf
.count_used
> r300
->cmdbuf
.count_reemit
)
571 r300FlushCmdBuf(r300
, __FUNCTION__
);
574 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
576 struct r300_dma_buffer
*dmabuf
;
577 int fd
= rmesa
->radeon
.dri
.fd
;
583 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
584 fprintf(stderr
, "%s\n", __FUNCTION__
);
586 if (rmesa
->dma
.flush
) {
587 rmesa
->dma
.flush(rmesa
);
590 if (rmesa
->dma
.current
.buf
)
591 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
593 if (rmesa
->dma
.nr_released_bufs
> 4)
594 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
596 dma
.context
= rmesa
->radeon
.dri
.hwContext
;
598 dma
.send_list
= NULL
;
599 dma
.send_sizes
= NULL
;
601 dma
.request_count
= 1;
602 dma
.request_size
= RADEON_BUFFER_SIZE
;
603 dma
.request_list
= &index
;
604 dma
.request_sizes
= &size
;
605 dma
.granted_count
= 0;
607 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
609 ret
= drmDMA(fd
, &dma
);
612 /* Try to release some buffers and wait until we can't get any more */
613 if (rmesa
->dma
.nr_released_bufs
) {
614 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
617 if (RADEON_DEBUG
& DEBUG_DMA
)
618 fprintf(stderr
, "Waiting for buffers\n");
620 radeonWaitForIdleLocked(&rmesa
->radeon
);
621 ret
= drmDMA(fd
, &dma
);
624 UNLOCK_HARDWARE(&rmesa
->radeon
);
625 fprintf(stderr
, "Error: Could not get dma buffer... exiting\n");
630 UNLOCK_HARDWARE(&rmesa
->radeon
);
632 if (RADEON_DEBUG
& DEBUG_DMA
)
633 fprintf(stderr
, "Allocated buffer %d\n", index
);
635 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
636 dmabuf
->buf
= &rmesa
->radeon
.radeonScreen
->buffers
->list
[index
];
637 dmabuf
->refcount
= 1;
639 rmesa
->dma
.current
.buf
= dmabuf
;
640 rmesa
->dma
.current
.address
= dmabuf
->buf
->address
;
641 rmesa
->dma
.current
.end
= dmabuf
->buf
->total
;
642 rmesa
->dma
.current
.start
= 0;
643 rmesa
->dma
.current
.ptr
= 0;
646 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
647 struct r300_dma_region
*region
, const char *caller
)
649 if (RADEON_DEBUG
& DEBUG_IOCTL
)
650 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
655 if (rmesa
->dma
.flush
)
656 rmesa
->dma
.flush(rmesa
);
658 if (--region
->buf
->refcount
== 0) {
659 drm_radeon_cmd_header_t
*cmd
;
661 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
662 fprintf(stderr
, "%s -- DISCARD BUF %d\n", __FUNCTION__
,
663 region
->buf
->buf
->idx
);
665 (drm_radeon_cmd_header_t
*) r300AllocCmdBuf(rmesa
,
668 cmd
->dma
.cmd_type
= R300_CMD_DMA_DISCARD
;
669 cmd
->dma
.buf_idx
= region
->buf
->buf
->idx
;
672 rmesa
->dma
.nr_released_bufs
++;
679 /* Allocates a region from rmesa->dma.current. If there isn't enough
680 * space in current, grab a new buffer (and discard what was left of current)
682 void r300AllocDmaRegion(r300ContextPtr rmesa
,
683 struct r300_dma_region
*region
,
684 int bytes
, int alignment
)
686 if (RADEON_DEBUG
& DEBUG_IOCTL
)
687 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
689 if (rmesa
->dma
.flush
)
690 rmesa
->dma
.flush(rmesa
);
693 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
696 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
697 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
699 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
700 r300RefillCurrentDmaRegion(rmesa
);
702 region
->start
= rmesa
->dma
.current
.start
;
703 region
->ptr
= rmesa
->dma
.current
.start
;
704 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
705 region
->address
= rmesa
->dma
.current
.address
;
706 region
->buf
= rmesa
->dma
.current
.buf
;
707 region
->buf
->refcount
++;
709 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
710 rmesa
->dma
.current
.start
=
711 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
713 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
716 /* Called via glXGetMemoryOffsetMESA() */
717 GLuint
r300GetMemoryOffsetMESA(__DRInativeDisplay
* dpy
, int scrn
,
718 const GLvoid
* pointer
)
720 GET_CURRENT_CONTEXT(ctx
);
721 r300ContextPtr rmesa
;
724 if (!ctx
|| !(rmesa
= R300_CONTEXT(ctx
))) {
725 fprintf(stderr
, "%s: no context\n", __FUNCTION__
);
729 if (!r300IsGartMemory(rmesa
, pointer
, 0))
732 if (rmesa
->radeon
.dri
.drmMinor
< 6)
735 card_offset
= r300GartOffsetFromVirtual(rmesa
, pointer
);
737 return card_offset
- rmesa
->radeon
.radeonScreen
->gart_base
;
740 GLboolean
r300IsGartMemory(r300ContextPtr rmesa
, const GLvoid
* pointer
,
744 (char *)pointer
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
745 int valid
= (size
>= 0 && offset
>= 0
746 && offset
+ size
< rmesa
->radeon
.radeonScreen
->gartTextures
.size
);
748 if (RADEON_DEBUG
& DEBUG_IOCTL
)
749 fprintf(stderr
, "r300IsGartMemory( %p ) : %d\n", pointer
,
755 GLuint
r300GartOffsetFromVirtual(r300ContextPtr rmesa
, const GLvoid
* pointer
)
758 (char *)pointer
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
760 //fprintf(stderr, "offset=%08x\n", offset);
762 if (offset
< 0 || offset
> rmesa
->radeon
.radeonScreen
->gartTextures
.size
)
765 return rmesa
->radeon
.radeonScreen
->gart_texture_offset
+ offset
;
768 void r300InitIoctlFuncs(struct dd_function_table
*functions
)
770 functions
->Clear
= r300Clear
;
771 functions
->Finish
= radeonFinish
;
772 functions
->Flush
= r300Flush
;