R300_PFS_NODE_LAST_NODE -> R300_PFS_NODE_OUTPUT_COLOR
[mesa.git] / src / mesa / drivers / dri / r300 / r300_ioctl.c
1 /*
2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
4 All Rights Reserved.
5
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.
9
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:
17
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.
21
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.
29
30 **************************************************************************/
31
32 /*
33 * Authors:
34 * Keith Whitwell <keith@tungstengraphics.com>
35 * Nicolai Haehnle <prefect_@gmx.net>
36 */
37
38 #include <sched.h>
39 #include <errno.h>
40
41 #include "glheader.h"
42 #include "imports.h"
43 #include "macros.h"
44 #include "context.h"
45 #include "swrast/swrast.h"
46
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"
55
56 #include "vblank.h"
57
58 #define CLEARBUFFER_COLOR 0x1
59 #define CLEARBUFFER_DEPTH 0x2
60 #define CLEARBUFFER_STENCIL 0x4
61
62 static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
63 {
64 GLcontext* ctx = r300->radeon.glCtx;
65 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
66 GLuint cboffset, cbpitch;
67 drm_r300_cmd_header_t* cmd2;
68 #ifdef CB_DPATH
69 r300ContextPtr rmesa=r300;
70 LOCAL_VARS;
71 #else
72 r300ContextPtr rmesa=r300;
73 LOCAL_VARS;
74 int i;
75 #endif
76
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);
81
82 if (buffer) {
83 cboffset = r300->radeon.radeonScreen->backOffset;
84 cbpitch = r300->radeon.radeonScreen->backPitch;
85 } else {
86 cboffset = r300->radeon.radeonScreen->frontOffset;
87 cbpitch = r300->radeon.radeonScreen->frontPitch;
88 }
89
90 cboffset += r300->radeon.radeonScreen->fbLocation;
91
92 #ifndef CB_DPATH
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;
96
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;
100
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;
104
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 */
109
110 R300_STATECHANGE(r300, txe);
111 r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
112
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);
120
121 R300_STATECHANGE(r300, at);
122 r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
123
124 R300_STATECHANGE(r300, bld);
125 r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
126 r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
127
128 if (r300->radeon.radeonScreen->cpp == 4)
129 cbpitch |= R300_COLOR_FORMAT_ARGB8888;
130 else
131 cbpitch |= R300_COLOR_FORMAT_RGB565;
132
133 if (r300->radeon.sarea->tiling_enabled)
134 cbpitch |= R300_COLOR_TILE_ENABLE;
135
136 R300_STATECHANGE(r300, cb);
137 r300->hw.cb.cmd[R300_CB_OFFSET] = cboffset;
138 r300->hw.cb.cmd[R300_CB_PITCH] = cbpitch;
139
140 R300_STATECHANGE(r300, unk221C);
141 r300->hw.unk221C.cmd[1] = R300_221C_CLEAR;
142
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);
147
148 R300_STATECHANGE(r300, ri);
149 for(i = 1; i <= 8; ++i)
150 r300->hw.ri.cmd[i] = R300_RS_INTERP_USED;
151
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;
156
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;
160
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);
168 } else {
169 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = 0;
170 }
171
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;
180
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;
189
190 /* MOV o0, t0 */
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);
195
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);
204
205 R300_STATECHANGE(r300, vpi);
206 ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->packet0.count = 8;
207
208 /* MOV o0, i0; */
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;
213
214 /* MOV o1, i1; */
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;
219
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);
226 /*
227 R300_STATECHANGE(r300, zb);
228 r300->hw.zb.cmd[R300_ZB_OFFSET] =
229 1024*4*300 +
230 r300->radeon.radeonScreen->frontOffset +
231 r300->radeon.radeonScreen->fbLocation;
232 r300->hw.zb.cmd[R300_ZB_PITCH] =
233 r300->radeon.radeonScreen->depthPitch;
234 */
235 } else {
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);
239 }
240
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;
257 }
258
259 /* Make sure we have enough space */
260 r300EnsureCmdBufSpace(r300, r300->hw.max_state_size + 9+8, __FUNCTION__);
261
262 r300EmitState(r300);
263 #else
264 #if 1
265 cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
266 end_3d(PASS_PREFIX_VOID);
267 #endif
268
269 R300_STATECHANGE(r300, cb);
270 reg_start(R300_RB3D_COLOROFFSET0, 0);
271 e32(cboffset);
272
273 if (r300->radeon.radeonScreen->cpp == 4)
274 cbpitch |= R300_COLOR_FORMAT_ARGB8888;
275 else
276 cbpitch |= R300_COLOR_FORMAT_RGB565;
277
278 if (r300->radeon.sarea->tiling_enabled)
279 cbpitch |= R300_COLOR_TILE_ENABLE;
280
281 reg_start(R300_RB3D_COLORPITCH0, 0);
282 e32(cbpitch);
283
284 R300_STATECHANGE(r300, cmk);
285 reg_start(R300_RB3D_COLORMASK, 0);
286
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));
292 } else {
293 e32(0);
294 }
295
296 R300_STATECHANGE(r300, zs);
297 reg_start(R300_RB3D_ZSTENCIL_CNTL_0, 2);
298
299 {
300 uint32_t t1, t2;
301
302 t1 = r300->hw.zs.cmd[R300_ZS_CNTL_0];
303 t2 = r300->hw.zs.cmd[R300_ZS_CNTL_1];
304
305 if (flags & CLEARBUFFER_DEPTH) {
306 t1 &= R300_RB3D_STENCIL_ENABLE;
307 t1 |= 0x6; // test and write
308
309 t2 &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
310 t2 |= (R300_ZS_ALWAYS<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
311 /*
312 R300_STATECHANGE(r300, zb);
313 r300->hw.zb.cmd[R300_ZB_OFFSET] =
314 1024*4*300 +
315 r300->radeon.radeonScreen->frontOffset +
316 r300->radeon.radeonScreen->fbLocation;
317 r300->hw.zb.cmd[R300_ZB_PITCH] =
318 r300->radeon.radeonScreen->depthPitch;
319 */
320 } else {
321 t1 &= R300_RB3D_STENCIL_ENABLE;
322 t1 |= R300_RB3D_Z_DISABLED_1; // disable
323
324 t2 &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
325 }
326
327 if (flags & CLEARBUFFER_STENCIL) {
328 t1 &= ~R300_RB3D_STENCIL_ENABLE;
329 t1 |= R300_RB3D_STENCIL_ENABLE;
330
331 t2 &=
332 ~((R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT));
333 t2 |=
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) ;
342 }
343
344 e32(t1);
345 e32(t2);
346 e32(r300->state.stencil.clear);
347 }
348
349 #endif
350
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]);
362
363 #if 1
364 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
365 e32(0x0000000a);
366
367
368 reg_start(0x4f18,0);
369 e32(0x00000003);
370 cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
371 #endif
372 }
373
374 #ifdef CB_DPATH
375 static void r300EmitClearState(GLcontext * ctx)
376 {
377 r300ContextPtr r300 = R300_CONTEXT(ctx);
378 r300ContextPtr rmesa=r300;
379 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
380 int i;
381 LOCAL_VARS;
382
383 R300_STATECHANGE(r300, vir[0]);
384 reg_start(R300_VAP_INPUT_ROUTE_0_0, 0);
385 e32(0x21030003);
386
387 R300_STATECHANGE(r300, vir[1]);
388 reg_start(R300_VAP_INPUT_ROUTE_1_0, 0);
389 e32(0xF688F688);
390
391 R300_STATECHANGE(r300, vic);
392 reg_start(R300_VAP_INPUT_CNTL_0, 1);
393 e32(0x00000001);
394 e32(0x00000405);
395
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 */
400
401
402 R300_STATECHANGE(r300, txe);
403 reg_start(R300_TX_ENABLE, 0);
404 e32(0);
405
406 R300_STATECHANGE(r300, vpt);
407 reg_start(R300_SE_VPORT_XSCALE, 5);
408 efloat(1.0);
409 efloat(dPriv->x);
410 efloat(1.0);
411 efloat(dPriv->y);
412 efloat(1.0);
413 efloat(0.0);
414
415 R300_STATECHANGE(r300, at);
416 reg_start(R300_PP_ALPHA_TEST, 0);
417 e32(0);
418
419 R300_STATECHANGE(r300, bld);
420 reg_start(R300_RB3D_CBLEND, 1);
421 e32(0);
422 e32(0);
423
424 R300_STATECHANGE(r300, unk221C);
425 reg_start(0x221C, 0);
426 e32(R300_221C_CLEAR);
427
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));
432
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);
437 }
438
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);
443 e32(0);
444
445 R300_STATECHANGE(r300, rr);
446 reg_start(R300_RS_ROUTE_0, 0);
447 e32(0x00004000);
448
449 R300_STATECHANGE(r300, fp);
450 reg_start(R300_PFS_CNTL_0, 2);
451 e32(0);
452 e32(0);
453 e32(0);
454 reg_start(R300_PFS_NODE_0, 3);
455 e32(0);
456 e32(0);
457 e32(0);
458 e32(R300_PFS_NODE_OUTPUT_COLOR);
459
460 R300_STATECHANGE(r300, fpi[0]);
461 R300_STATECHANGE(r300, fpi[1]);
462 R300_STATECHANGE(r300, fpi[2]);
463 R300_STATECHANGE(r300, fpi[3]);
464
465 reg_start(R300_PFS_INSTR0_0, 0);
466 e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
467
468 reg_start(R300_PFS_INSTR1_0, 0);
469 e32(FP_SELC(0,NO,XYZ,FP_TMP(0),0,0));
470
471 reg_start(R300_PFS_INSTR2_0, 0);
472 e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
473
474 reg_start(R300_PFS_INSTR3_0, 0);
475 e32(FP_SELA(0,NO,W,FP_TMP(0),0,0));
476
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));
482 e32(0);
483 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
484
485 R300_STATECHANGE(r300, vpi);
486 vsf_start_fragment(0x0, 8);
487 e32(VP_OUT(ADD,OUT,0,XYZW));
488 e32(VP_IN(IN,0));
489 e32(VP_ZERO());
490 e32(0);
491
492 e32(VP_OUT(ADD,OUT,1,XYZW));
493 e32(VP_IN(IN,1));
494 e32(VP_ZERO());
495 e32(0);
496
497 /*reg_start(0x4500,0);
498 e32(2560-1);*/
499 }
500 #endif
501
502 /**
503 * Buffer clear
504 */
505 static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
506 GLint cx, GLint cy, GLint cw, GLint ch)
507 {
508 r300ContextPtr r300 = R300_CONTEXT(ctx);
509 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
510 int flags = 0;
511 int bits = 0;
512 int swapped;
513
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);
517
518 {
519 LOCK_HARDWARE(&r300->radeon);
520 UNLOCK_HARDWARE(&r300->radeon);
521 if (dPriv->numClipRects == 0)
522 return;
523 }
524
525 if (mask & BUFFER_BIT_FRONT_LEFT) {
526 flags |= BUFFER_BIT_FRONT_LEFT;
527 mask &= ~BUFFER_BIT_FRONT_LEFT;
528 }
529
530 if (mask & BUFFER_BIT_BACK_LEFT) {
531 flags |= BUFFER_BIT_BACK_LEFT;
532 mask &= ~BUFFER_BIT_BACK_LEFT;
533 }
534
535 if (mask & BUFFER_BIT_DEPTH) {
536 bits |= CLEARBUFFER_DEPTH;
537 mask &= ~BUFFER_BIT_DEPTH;
538 }
539
540 if ( (mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) {
541 bits |= CLEARBUFFER_STENCIL;
542 mask &= ~BUFFER_BIT_STENCIL;
543 }
544
545 if (mask) {
546 if (RADEON_DEBUG & DEBUG_FALLBACKS)
547 fprintf(stderr, "%s: swrast clear, mask: %x\n",
548 __FUNCTION__, mask);
549 _swrast_Clear(ctx, mask, all, cx, cy, cw, ch);
550 }
551
552 swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1);
553
554 #ifdef CB_DPATH
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__);
558 if(flags || bits)
559 r300EmitClearState(ctx);
560 #endif
561
562 if (flags & BUFFER_BIT_FRONT_LEFT) {
563 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);
564 bits = 0;
565 }
566
567 if (flags & BUFFER_BIT_BACK_LEFT) {
568 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);
569 bits = 0;
570 }
571
572 if (bits)
573 r300ClearBuffer(r300, bits, 0);
574
575 #ifndef CB_DPATH
576 /* Recalculate the hardware state. This could be done more efficiently,
577 * but do keep it like this for now.
578 */
579 r300ResetHwState(r300);
580
581 /* r300ClearBuffer has trampled all over the hardware state.. */
582 r300->hw.all_dirty=GL_TRUE;
583 #endif
584 }
585
586
587 void r300Flush(GLcontext * ctx)
588 {
589 r300ContextPtr r300 = R300_CONTEXT(ctx);
590
591 if (RADEON_DEBUG & DEBUG_IOCTL)
592 fprintf(stderr, "%s\n", __FUNCTION__);
593
594 if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
595 r300FlushCmdBuf(r300, __FUNCTION__);
596 }
597
598 #ifdef USER_BUFFERS
599 #include "radeon_mm.h"
600
601 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
602 {
603 struct r300_dma_buffer *dmabuf;
604 int fd = rmesa->radeon.dri.fd;
605 int index = 0;
606 int size = 0;
607 drmDMAReq dma;
608 int ret;
609
610 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
611 fprintf(stderr, "%s\n", __FUNCTION__);
612
613 if (rmesa->dma.flush) {
614 rmesa->dma.flush(rmesa);
615 }
616
617 if (rmesa->dma.current.buf)
618 r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
619
620 if (rmesa->dma.nr_released_bufs > 4)
621 r300FlushCmdBuf(rmesa, __FUNCTION__);
622
623 dmabuf = CALLOC_STRUCT(r300_dma_buffer);
624 dmabuf->buf = (void *)1; /* hack */
625 dmabuf->refcount = 1;
626
627 dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16);
628
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;
634 }
635
636 void r300ReleaseDmaRegion(r300ContextPtr rmesa,
637 struct r300_dma_region *region, const char *caller)
638 {
639 if (RADEON_DEBUG & DEBUG_IOCTL)
640 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
641
642 if (!region->buf)
643 return;
644
645 if (rmesa->dma.flush)
646 rmesa->dma.flush(rmesa);
647
648 if (--region->buf->refcount == 0) {
649 radeon_mm_free(rmesa, region->buf->id);
650 FREE(region->buf);
651 rmesa->dma.nr_released_bufs++;
652 }
653
654 region->buf = 0;
655 region->start = 0;
656 }
657
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)
660 */
661 void r300AllocDmaRegion(r300ContextPtr rmesa,
662 struct r300_dma_region *region,
663 int bytes, int alignment)
664 {
665 if (RADEON_DEBUG & DEBUG_IOCTL)
666 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
667
668 if (rmesa->dma.flush)
669 rmesa->dma.flush(rmesa);
670
671 if (region->buf)
672 r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
673
674 alignment--;
675 rmesa->dma.current.start = rmesa->dma.current.ptr =
676 (rmesa->dma.current.ptr + alignment) & ~alignment;
677
678 if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
679 r300RefillCurrentDmaRegion(rmesa);
680
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++;
687
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;
691
692 assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
693 }
694
695 #else
696 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
697 {
698 struct r300_dma_buffer *dmabuf;
699 int fd = rmesa->radeon.dri.fd;
700 int index = 0;
701 int size = 0;
702 drmDMAReq dma;
703 int ret;
704
705 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
706 fprintf(stderr, "%s\n", __FUNCTION__);
707
708 if (rmesa->dma.flush) {
709 rmesa->dma.flush(rmesa);
710 }
711
712 if (rmesa->dma.current.buf)
713 r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
714
715 if (rmesa->dma.nr_released_bufs > 4)
716 r300FlushCmdBuf(rmesa, __FUNCTION__);
717
718 dma.context = rmesa->radeon.dri.hwContext;
719 dma.send_count = 0;
720 dma.send_list = NULL;
721 dma.send_sizes = NULL;
722 dma.flags = 0;
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;
728
729 LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
730
731 ret = drmDMA(fd, &dma);
732
733 if (ret != 0) {
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__);
737 }
738
739 if (RADEON_DEBUG & DEBUG_DMA)
740 fprintf(stderr, "Waiting for buffers\n");
741
742 radeonWaitForIdleLocked(&rmesa->radeon);
743 ret = drmDMA(fd, &dma);
744
745 if (ret != 0) {
746 UNLOCK_HARDWARE(&rmesa->radeon);
747 fprintf(stderr, "Error: Could not get dma buffer... exiting\n");
748 exit(-1);
749 }
750 }
751
752 UNLOCK_HARDWARE(&rmesa->radeon);
753
754 if (RADEON_DEBUG & DEBUG_DMA)
755 fprintf(stderr, "Allocated buffer %d\n", index);
756
757 dmabuf = CALLOC_STRUCT(r300_dma_buffer);
758 dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];
759 dmabuf->refcount = 1;
760
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;
766 }
767
768 void r300ReleaseDmaRegion(r300ContextPtr rmesa,
769 struct r300_dma_region *region, const char *caller)
770 {
771 if (RADEON_DEBUG & DEBUG_IOCTL)
772 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
773
774 if (!region->buf)
775 return;
776
777 if (rmesa->dma.flush)
778 rmesa->dma.flush(rmesa);
779
780 if (--region->buf->refcount == 0) {
781 drm_radeon_cmd_header_t *cmd;
782
783 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
784 fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
785 region->buf->buf->idx);
786 cmd =
787 (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
788 sizeof(*cmd) / 4,
789 __FUNCTION__);
790 cmd->dma.cmd_type = R300_CMD_DMA_DISCARD;
791 cmd->dma.buf_idx = region->buf->buf->idx;
792
793 FREE(region->buf);
794 rmesa->dma.nr_released_bufs++;
795 }
796
797 region->buf = 0;
798 region->start = 0;
799 }
800
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)
803 */
804 void r300AllocDmaRegion(r300ContextPtr rmesa,
805 struct r300_dma_region *region,
806 int bytes, int alignment)
807 {
808 if (RADEON_DEBUG & DEBUG_IOCTL)
809 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
810
811 if (rmesa->dma.flush)
812 rmesa->dma.flush(rmesa);
813
814 if (region->buf)
815 r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
816
817 alignment--;
818 rmesa->dma.current.start = rmesa->dma.current.ptr =
819 (rmesa->dma.current.ptr + alignment) & ~alignment;
820
821 if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
822 r300RefillCurrentDmaRegion(rmesa);
823
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++;
830
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;
834
835 assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
836 }
837
838 #endif
839
840 /* Called via glXGetMemoryOffsetMESA() */
841 GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
842 const GLvoid * pointer)
843 {
844 GET_CURRENT_CONTEXT(ctx);
845 r300ContextPtr rmesa;
846 GLuint card_offset;
847
848 if (!ctx || !(rmesa = R300_CONTEXT(ctx))) {
849 fprintf(stderr, "%s: no context\n", __FUNCTION__);
850 return ~0;
851 }
852
853 if (!r300IsGartMemory(rmesa, pointer, 0))
854 return ~0;
855
856 if (rmesa->radeon.dri.drmMinor < 6)
857 return ~0;
858
859 card_offset = r300GartOffsetFromVirtual(rmesa, pointer);
860
861 return card_offset - rmesa->radeon.radeonScreen->gart_base;
862 }
863
864 GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
865 GLint size)
866 {
867 int offset =
868 (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
869 int valid = (size >= 0 && offset >= 0
870 && offset + size < rmesa->radeon.radeonScreen->gartTextures.size);
871
872 if (RADEON_DEBUG & DEBUG_IOCTL)
873 fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
874 valid);
875
876 return valid;
877 }
878
879 GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
880 {
881 int offset =
882 (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
883
884 //fprintf(stderr, "offset=%08x\n", offset);
885
886 if (offset < 0 || offset > rmesa->radeon.radeonScreen->gartTextures.size)
887 return ~0;
888 else
889 return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
890 }
891
892 void r300InitIoctlFuncs(struct dd_function_table *functions)
893 {
894 functions->Clear = r300Clear;
895 functions->Finish = radeonFinish;
896 functions->Flush = r300Flush;
897 }