More optimal r300Clear.
[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 CB_DPATH
59
60 #define CLEARBUFFER_COLOR 0x1
61 #define CLEARBUFFER_DEPTH 0x2
62 #define CLEARBUFFER_STENCIL 0x4
63
64 static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
65 {
66 GLcontext* ctx = r300->radeon.glCtx;
67 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
68 GLuint cboffset, cbpitch;
69 drm_r300_cmd_header_t* cmd2;
70 #ifdef CB_DPATH
71 r300ContextPtr rmesa=r300;
72 LOCAL_VARS;
73 #else
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)->unchecked_state.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)->unchecked_state.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 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;
131
132 R300_STATECHANGE(r300, unk221C);
133 r300->hw.unk221C.cmd[1] = R300_221C_CLEAR;
134
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);
139
140 R300_STATECHANGE(r300, ri);
141 for(i = 1; i <= 8; ++i)
142 r300->hw.ri.cmd[i] = R300_RS_INTERP_USED;
143
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;
148
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;
152
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);
160 } else {
161 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = 0;
162 }
163
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;
172
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;
181
182 /* MOV o0, t0 */
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);
187
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);
196
197 R300_STATECHANGE(r300, vpi);
198 ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->unchecked_state.count = 8;
199
200 /* MOV o0, i0; */
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;
205
206 /* MOV o1, i1; */
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;
211
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);
218 /*
219 R300_STATECHANGE(r300, zb);
220 r300->hw.zb.cmd[R300_ZB_OFFSET] =
221 1024*4*300 +
222 r300->radeon.radeonScreen->frontOffset +
223 r300->radeon.radeonScreen->fbLocation;
224 r300->hw.zb.cmd[R300_ZB_PITCH] =
225 r300->radeon.radeonScreen->depthPitch;
226 */
227 } else {
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);
231 }
232
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;
249 }
250
251 /* Make sure we have enough space */
252 r300EnsureCmdBufSpace(r300, r300->hw.max_state_size + 9+8, __FUNCTION__);
253
254 r300EmitState(r300);
255 #else
256 R300_STATECHANGE(r300, cb);
257 reg_start(R300_RB3D_COLOROFFSET0, 0);
258 e32(cboffset);
259
260 reg_start(R300_RB3D_COLORPITCH0, 0);
261 e32(cbpitch | R300_COLOR_UNKNOWN_22_23);
262
263 R300_STATECHANGE(r300, cmk);
264 reg_start(R300_RB3D_COLORMASK, 0);
265
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));
271 } else {
272 e32(0);
273 }
274
275 R300_STATECHANGE(r300, zs);
276 reg_start(R300_RB3D_ZSTENCIL_CNTL_0, 2);
277
278 {
279 uint32_t t1, t2;
280
281 t1 = r300->hw.zs.cmd[R300_ZS_CNTL_0];
282 t2 = r300->hw.zs.cmd[R300_ZS_CNTL_1];
283
284 if (flags & CLEARBUFFER_DEPTH) {
285 t1 &= R300_RB3D_STENCIL_ENABLE;
286 t1 |= 0x6; // test and write
287
288 t2 &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
289 t2 |= (R300_ZS_ALWAYS<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
290 /*
291 R300_STATECHANGE(r300, zb);
292 r300->hw.zb.cmd[R300_ZB_OFFSET] =
293 1024*4*300 +
294 r300->radeon.radeonScreen->frontOffset +
295 r300->radeon.radeonScreen->fbLocation;
296 r300->hw.zb.cmd[R300_ZB_PITCH] =
297 r300->radeon.radeonScreen->depthPitch;
298 */
299 } else {
300 t1 &= R300_RB3D_STENCIL_ENABLE;
301 t1 |= R300_RB3D_Z_DISABLED_1; // disable
302
303 t2 &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
304 }
305
306 if (flags & CLEARBUFFER_STENCIL) {
307 t1 &= ~R300_RB3D_STENCIL_ENABLE;
308 t1 |= R300_RB3D_STENCIL_ENABLE;
309
310 t2 &=
311 ~((R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT));
312 t2 |=
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) ;
321 }
322
323 e32(t1);
324 e32(t2);
325 e32(r300->state.stencil.clear);
326 }
327
328 #endif
329
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]);
341 }
342
343 #ifdef CB_DPATH
344 static void r300EmitClearState(GLcontext * ctx)
345 {
346 r300ContextPtr r300 = R300_CONTEXT(ctx);
347 r300ContextPtr rmesa=r300;
348 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
349 int i;
350 LOCAL_VARS;
351
352 R300_STATECHANGE(r300, vir[0]);
353 reg_start(R300_VAP_INPUT_ROUTE_0_0, 0);
354 e32(0x21030003);
355
356 R300_STATECHANGE(r300, vir[1]);
357 reg_start(R300_VAP_INPUT_ROUTE_1_0, 0);
358 e32(0xF688F688);
359
360 R300_STATECHANGE(r300, vic);
361 reg_start(R300_VAP_INPUT_CNTL_0, 1);
362 e32(0x00000001);
363 e32(0x00000405);
364
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 */
369
370
371 R300_STATECHANGE(r300, txe);
372 reg_start(R300_TX_ENABLE, 0);
373 e32(0);
374
375 R300_STATECHANGE(r300, vpt);
376 reg_start(R300_SE_VPORT_XSCALE, 5);
377 efloat(1.0);
378 efloat(dPriv->x);
379 efloat(1.0);
380 efloat(dPriv->y);
381 efloat(1.0);
382 efloat(0.0);
383
384 R300_STATECHANGE(r300, at);
385 reg_start(R300_PP_ALPHA_TEST, 0);
386 e32(0);
387
388 R300_STATECHANGE(r300, bld);
389 reg_start(R300_RB3D_CBLEND, 1);
390 e32(0);
391 e32(0);
392
393 R300_STATECHANGE(r300, unk221C);
394 reg_start(0x221C, 0);
395 e32(R300_221C_CLEAR);
396
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));
401
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);
406 }
407
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);
412 e32(0);
413
414 R300_STATECHANGE(r300, rr);
415 reg_start(R300_RS_ROUTE_0, 0);
416 e32(0x00004000);
417
418 R300_STATECHANGE(r300, fp);
419 reg_start(R300_PFS_CNTL_0, 2);
420 e32(0);
421 e32(0);
422 e32(0);
423 reg_start(R300_PFS_NODE_0, 3);
424 e32(0);
425 e32(0);
426 e32(0);
427 e32(R300_PFS_NODE_LAST_NODE);
428
429 R300_STATECHANGE(r300, fpi[0]);
430 R300_STATECHANGE(r300, fpi[1]);
431 R300_STATECHANGE(r300, fpi[2]);
432 R300_STATECHANGE(r300, fpi[3]);
433
434 reg_start(R300_PFS_INSTR0_0, 0);
435 e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
436
437 reg_start(R300_PFS_INSTR1_0, 0);
438 e32(FP_SELC(0,NO,XYZ,FP_TMP(0),0,0));
439
440 reg_start(R300_PFS_INSTR2_0, 0);
441 e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
442
443 reg_start(R300_PFS_INSTR3_0, 0);
444 e32(FP_SELA(0,NO,W,FP_TMP(0),0,0));
445
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));
451 e32(0);
452 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
453
454 R300_STATECHANGE(r300, vpi);
455 vsf_start_fragment(0x0, 8);
456 e32(VP_OUT(ADD,OUT,0,XYZW));
457 e32(VP_IN(IN,0));
458 e32(VP_ZERO());
459 e32(0);
460
461 e32(VP_OUT(ADD,OUT,1,XYZW));
462 e32(VP_IN(IN,1));
463 e32(VP_ZERO());
464 e32(0);
465
466 }
467 #endif
468
469 /**
470 * Buffer clear
471 */
472 static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
473 GLint cx, GLint cy, GLint cw, GLint ch)
474 {
475 r300ContextPtr r300 = R300_CONTEXT(ctx);
476 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
477 int flags = 0;
478 int bits = 0;
479 int swapped;
480
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);
484
485 {
486 LOCK_HARDWARE(&r300->radeon);
487 UNLOCK_HARDWARE(&r300->radeon);
488 if (dPriv->numClipRects == 0)
489 return;
490 }
491
492 if (mask & BUFFER_BIT_FRONT_LEFT) {
493 flags |= BUFFER_BIT_FRONT_LEFT;
494 mask &= ~BUFFER_BIT_FRONT_LEFT;
495 }
496
497 if (mask & BUFFER_BIT_BACK_LEFT) {
498 flags |= BUFFER_BIT_BACK_LEFT;
499 mask &= ~BUFFER_BIT_BACK_LEFT;
500 }
501
502 if (mask & BUFFER_BIT_DEPTH) {
503 bits |= CLEARBUFFER_DEPTH;
504 mask &= ~BUFFER_BIT_DEPTH;
505 }
506
507 if ( (mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) {
508 bits |= CLEARBUFFER_STENCIL;
509 mask &= ~BUFFER_BIT_STENCIL;
510 }
511
512 if (mask) {
513 if (RADEON_DEBUG & DEBUG_FALLBACKS)
514 fprintf(stderr, "%s: swrast clear, mask: %x\n",
515 __FUNCTION__, mask);
516 _swrast_Clear(ctx, mask, all, cx, cy, cw, ch);
517 }
518
519 swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1);
520
521 #ifdef CB_DPATH
522 if(flags || bits)
523 r300EmitClearState(ctx);
524 #endif
525
526 if (flags & BUFFER_BIT_FRONT_LEFT) {
527 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);
528 bits = 0;
529 }
530
531 if (flags & BUFFER_BIT_BACK_LEFT) {
532 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);
533 bits = 0;
534 }
535
536 if (bits)
537 r300ClearBuffer(r300, bits, 0);
538
539 #ifndef CB_DPATH
540 /* Recalculate the hardware state. This could be done more efficiently,
541 * but do keep it like this for now.
542 */
543 r300ResetHwState(r300);
544
545 /* r300ClearBuffer has trampled all over the hardware state.. */
546 r300->hw.all_dirty=GL_TRUE;
547 #endif
548 }
549
550 void r300Flush(GLcontext * ctx)
551 {
552 r300ContextPtr r300 = R300_CONTEXT(ctx);
553
554 if (RADEON_DEBUG & DEBUG_IOCTL)
555 fprintf(stderr, "%s\n", __FUNCTION__);
556
557 if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
558 r300FlushCmdBuf(r300, __FUNCTION__);
559 }
560
561 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
562 {
563 struct r300_dma_buffer *dmabuf;
564 int fd = rmesa->radeon.dri.fd;
565 int index = 0;
566 int size = 0;
567 drmDMAReq dma;
568 int ret;
569
570 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
571 fprintf(stderr, "%s\n", __FUNCTION__);
572
573 if (rmesa->dma.flush) {
574 rmesa->dma.flush(rmesa);
575 }
576
577 if (rmesa->dma.current.buf)
578 r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
579
580 if (rmesa->dma.nr_released_bufs > 4)
581 r300FlushCmdBuf(rmesa, __FUNCTION__);
582
583 dma.context = rmesa->radeon.dri.hwContext;
584 dma.send_count = 0;
585 dma.send_list = NULL;
586 dma.send_sizes = NULL;
587 dma.flags = 0;
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;
593
594 LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
595
596 ret = drmDMA(fd, &dma);
597
598 if (ret != 0) {
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__);
602 }
603
604 if (RADEON_DEBUG & DEBUG_DMA)
605 fprintf(stderr, "Waiting for buffers\n");
606
607 radeonWaitForIdleLocked(&rmesa->radeon);
608 ret = drmDMA(fd, &dma);
609
610 if (ret != 0) {
611 UNLOCK_HARDWARE(&rmesa->radeon);
612 fprintf(stderr, "Error: Could not get dma buffer... exiting\n");
613 exit(-1);
614 }
615 }
616
617 UNLOCK_HARDWARE(&rmesa->radeon);
618
619 if (RADEON_DEBUG & DEBUG_DMA)
620 fprintf(stderr, "Allocated buffer %d\n", index);
621
622 dmabuf = CALLOC_STRUCT(r300_dma_buffer);
623 dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];
624 dmabuf->refcount = 1;
625
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;
631 }
632
633 void r300ReleaseDmaRegion(r300ContextPtr rmesa,
634 struct r300_dma_region *region, const char *caller)
635 {
636 if (RADEON_DEBUG & DEBUG_IOCTL)
637 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
638
639 if (!region->buf)
640 return;
641
642 if (rmesa->dma.flush)
643 rmesa->dma.flush(rmesa);
644
645 if (--region->buf->refcount == 0) {
646 drm_radeon_cmd_header_t *cmd;
647
648 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
649 fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
650 region->buf->buf->idx);
651 cmd =
652 (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
653 sizeof(*cmd) / 4,
654 __FUNCTION__);
655 cmd->dma.cmd_type = R300_CMD_DMA_DISCARD;
656 cmd->dma.buf_idx = region->buf->buf->idx;
657
658 FREE(region->buf);
659 rmesa->dma.nr_released_bufs++;
660 }
661
662 region->buf = 0;
663 region->start = 0;
664 }
665
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)
668 */
669 void r300AllocDmaRegion(r300ContextPtr rmesa,
670 struct r300_dma_region *region,
671 int bytes, int alignment)
672 {
673 if (RADEON_DEBUG & DEBUG_IOCTL)
674 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
675
676 if (rmesa->dma.flush)
677 rmesa->dma.flush(rmesa);
678
679 if (region->buf)
680 r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
681
682 alignment--;
683 rmesa->dma.current.start = rmesa->dma.current.ptr =
684 (rmesa->dma.current.ptr + alignment) & ~alignment;
685
686 if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
687 r300RefillCurrentDmaRegion(rmesa);
688
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++;
695
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;
699
700 assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
701 }
702
703 /* Called via glXGetMemoryOffsetMESA() */
704 GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
705 const GLvoid * pointer)
706 {
707 GET_CURRENT_CONTEXT(ctx);
708 r300ContextPtr rmesa;
709 GLuint card_offset;
710
711 if (!ctx || !(rmesa = R300_CONTEXT(ctx))) {
712 fprintf(stderr, "%s: no context\n", __FUNCTION__);
713 return ~0;
714 }
715
716 if (!r300IsGartMemory(rmesa, pointer, 0))
717 return ~0;
718
719 if (rmesa->radeon.dri.drmMinor < 6)
720 return ~0;
721
722 card_offset = r300GartOffsetFromVirtual(rmesa, pointer);
723
724 return card_offset - rmesa->radeon.radeonScreen->gart_base;
725 }
726
727 GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
728 GLint size)
729 {
730 int offset =
731 (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
732 int valid = (size >= 0 && offset >= 0
733 && offset + size < rmesa->radeon.radeonScreen->gartTextures.size);
734
735 if (RADEON_DEBUG & DEBUG_IOCTL)
736 fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
737 valid);
738
739 return valid;
740 }
741
742 GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
743 {
744 int offset =
745 (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
746
747 //fprintf(stderr, "offset=%08x\n", offset);
748
749 if (offset < 0 || offset > rmesa->radeon.radeonScreen->gartTextures.size)
750 return ~0;
751 else
752 return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
753 }
754
755 void r300InitIoctlFuncs(struct dd_function_table *functions)
756 {
757 functions->Clear = r300Clear;
758 functions->Finish = radeonFinish;
759 functions->Flush = r300Flush;
760 }