255f17aee9fdaa03079c97d3ba9d5d578572c39a
[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 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)->unchecked_state.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_LAST_NODE;
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)->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;
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)->unchecked_state.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 R300_STATECHANGE(r300, cb);
265 reg_start(R300_RB3D_COLOROFFSET0, 0);
266 e32(cboffset);
267
268 if (r300->radeon.radeonScreen->cpp == 4)
269 cbpitch |= R300_COLOR_FORMAT_ARGB8888;
270 else
271 cbpitch |= R300_COLOR_FORMAT_RGB565;
272
273 reg_start(R300_RB3D_COLORPITCH0, 0);
274 e32(cbpitch);
275
276 R300_STATECHANGE(r300, cmk);
277 reg_start(R300_RB3D_COLORMASK, 0);
278
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));
284 } else {
285 e32(0);
286 }
287
288 R300_STATECHANGE(r300, zs);
289 reg_start(R300_RB3D_ZSTENCIL_CNTL_0, 2);
290
291 {
292 uint32_t t1, t2;
293
294 t1 = r300->hw.zs.cmd[R300_ZS_CNTL_0];
295 t2 = r300->hw.zs.cmd[R300_ZS_CNTL_1];
296
297 if (flags & CLEARBUFFER_DEPTH) {
298 t1 &= R300_RB3D_STENCIL_ENABLE;
299 t1 |= 0x6; // test and write
300
301 t2 &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
302 t2 |= (R300_ZS_ALWAYS<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
303 /*
304 R300_STATECHANGE(r300, zb);
305 r300->hw.zb.cmd[R300_ZB_OFFSET] =
306 1024*4*300 +
307 r300->radeon.radeonScreen->frontOffset +
308 r300->radeon.radeonScreen->fbLocation;
309 r300->hw.zb.cmd[R300_ZB_PITCH] =
310 r300->radeon.radeonScreen->depthPitch;
311 */
312 } else {
313 t1 &= R300_RB3D_STENCIL_ENABLE;
314 t1 |= R300_RB3D_Z_DISABLED_1; // disable
315
316 t2 &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
317 }
318
319 if (flags & CLEARBUFFER_STENCIL) {
320 t1 &= ~R300_RB3D_STENCIL_ENABLE;
321 t1 |= R300_RB3D_STENCIL_ENABLE;
322
323 t2 &=
324 ~((R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT));
325 t2 |=
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) ;
334 }
335
336 e32(t1);
337 e32(t2);
338 e32(r300->state.stencil.clear);
339 }
340
341 #endif
342
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]);
354 }
355
356 #ifdef CB_DPATH
357 static void r300EmitClearState(GLcontext * ctx)
358 {
359 r300ContextPtr r300 = R300_CONTEXT(ctx);
360 r300ContextPtr rmesa=r300;
361 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
362 int i;
363 LOCAL_VARS;
364
365 R300_STATECHANGE(r300, vir[0]);
366 reg_start(R300_VAP_INPUT_ROUTE_0_0, 0);
367 e32(0x21030003);
368
369 R300_STATECHANGE(r300, vir[1]);
370 reg_start(R300_VAP_INPUT_ROUTE_1_0, 0);
371 e32(0xF688F688);
372
373 R300_STATECHANGE(r300, vic);
374 reg_start(R300_VAP_INPUT_CNTL_0, 1);
375 e32(0x00000001);
376 e32(0x00000405);
377
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 */
382
383
384 R300_STATECHANGE(r300, txe);
385 reg_start(R300_TX_ENABLE, 0);
386 e32(0);
387
388 R300_STATECHANGE(r300, vpt);
389 reg_start(R300_SE_VPORT_XSCALE, 5);
390 efloat(1.0);
391 efloat(dPriv->x);
392 efloat(1.0);
393 efloat(dPriv->y);
394 efloat(1.0);
395 efloat(0.0);
396
397 R300_STATECHANGE(r300, at);
398 reg_start(R300_PP_ALPHA_TEST, 0);
399 e32(0);
400
401 R300_STATECHANGE(r300, bld);
402 reg_start(R300_RB3D_CBLEND, 1);
403 e32(0);
404 e32(0);
405
406 R300_STATECHANGE(r300, unk221C);
407 reg_start(0x221C, 0);
408 e32(R300_221C_CLEAR);
409
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));
414
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);
419 }
420
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);
425 e32(0);
426
427 R300_STATECHANGE(r300, rr);
428 reg_start(R300_RS_ROUTE_0, 0);
429 e32(0x00004000);
430
431 R300_STATECHANGE(r300, fp);
432 reg_start(R300_PFS_CNTL_0, 2);
433 e32(0);
434 e32(0);
435 e32(0);
436 reg_start(R300_PFS_NODE_0, 3);
437 e32(0);
438 e32(0);
439 e32(0);
440 e32(R300_PFS_NODE_LAST_NODE);
441
442 R300_STATECHANGE(r300, fpi[0]);
443 R300_STATECHANGE(r300, fpi[1]);
444 R300_STATECHANGE(r300, fpi[2]);
445 R300_STATECHANGE(r300, fpi[3]);
446
447 reg_start(R300_PFS_INSTR0_0, 0);
448 e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
449
450 reg_start(R300_PFS_INSTR1_0, 0);
451 e32(FP_SELC(0,NO,XYZ,FP_TMP(0),0,0));
452
453 reg_start(R300_PFS_INSTR2_0, 0);
454 e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
455
456 reg_start(R300_PFS_INSTR3_0, 0);
457 e32(FP_SELA(0,NO,W,FP_TMP(0),0,0));
458
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));
464 e32(0);
465 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
466
467 R300_STATECHANGE(r300, vpi);
468 vsf_start_fragment(0x0, 8);
469 e32(VP_OUT(ADD,OUT,0,XYZW));
470 e32(VP_IN(IN,0));
471 e32(VP_ZERO());
472 e32(0);
473
474 e32(VP_OUT(ADD,OUT,1,XYZW));
475 e32(VP_IN(IN,1));
476 e32(VP_ZERO());
477 e32(0);
478
479 }
480 #endif
481
482 /**
483 * Buffer clear
484 */
485 static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
486 GLint cx, GLint cy, GLint cw, GLint ch)
487 {
488 r300ContextPtr r300 = R300_CONTEXT(ctx);
489 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
490 int flags = 0;
491 int bits = 0;
492 int swapped;
493
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);
497
498 {
499 LOCK_HARDWARE(&r300->radeon);
500 UNLOCK_HARDWARE(&r300->radeon);
501 if (dPriv->numClipRects == 0)
502 return;
503 }
504
505 if (mask & BUFFER_BIT_FRONT_LEFT) {
506 flags |= BUFFER_BIT_FRONT_LEFT;
507 mask &= ~BUFFER_BIT_FRONT_LEFT;
508 }
509
510 if (mask & BUFFER_BIT_BACK_LEFT) {
511 flags |= BUFFER_BIT_BACK_LEFT;
512 mask &= ~BUFFER_BIT_BACK_LEFT;
513 }
514
515 if (mask & BUFFER_BIT_DEPTH) {
516 bits |= CLEARBUFFER_DEPTH;
517 mask &= ~BUFFER_BIT_DEPTH;
518 }
519
520 if ( (mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) {
521 bits |= CLEARBUFFER_STENCIL;
522 mask &= ~BUFFER_BIT_STENCIL;
523 }
524
525 if (mask) {
526 if (RADEON_DEBUG & DEBUG_FALLBACKS)
527 fprintf(stderr, "%s: swrast clear, mask: %x\n",
528 __FUNCTION__, mask);
529 _swrast_Clear(ctx, mask, all, cx, cy, cw, ch);
530 }
531
532 swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1);
533
534 #ifdef CB_DPATH
535 if(flags || bits)
536 r300EmitClearState(ctx);
537 #endif
538
539 if (flags & BUFFER_BIT_FRONT_LEFT) {
540 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);
541 bits = 0;
542 }
543
544 if (flags & BUFFER_BIT_BACK_LEFT) {
545 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);
546 bits = 0;
547 }
548
549 if (bits)
550 r300ClearBuffer(r300, bits, 0);
551
552 #ifndef CB_DPATH
553 /* Recalculate the hardware state. This could be done more efficiently,
554 * but do keep it like this for now.
555 */
556 r300ResetHwState(r300);
557
558 /* r300ClearBuffer has trampled all over the hardware state.. */
559 r300->hw.all_dirty=GL_TRUE;
560 #endif
561 }
562
563 void r300Flush(GLcontext * ctx)
564 {
565 r300ContextPtr r300 = R300_CONTEXT(ctx);
566
567 if (RADEON_DEBUG & DEBUG_IOCTL)
568 fprintf(stderr, "%s\n", __FUNCTION__);
569
570 if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
571 r300FlushCmdBuf(r300, __FUNCTION__);
572 }
573
574 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
575 {
576 struct r300_dma_buffer *dmabuf;
577 int fd = rmesa->radeon.dri.fd;
578 int index = 0;
579 int size = 0;
580 drmDMAReq dma;
581 int ret;
582
583 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
584 fprintf(stderr, "%s\n", __FUNCTION__);
585
586 if (rmesa->dma.flush) {
587 rmesa->dma.flush(rmesa);
588 }
589
590 if (rmesa->dma.current.buf)
591 r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
592
593 if (rmesa->dma.nr_released_bufs > 4)
594 r300FlushCmdBuf(rmesa, __FUNCTION__);
595
596 dma.context = rmesa->radeon.dri.hwContext;
597 dma.send_count = 0;
598 dma.send_list = NULL;
599 dma.send_sizes = NULL;
600 dma.flags = 0;
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;
606
607 LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
608
609 ret = drmDMA(fd, &dma);
610
611 if (ret != 0) {
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__);
615 }
616
617 if (RADEON_DEBUG & DEBUG_DMA)
618 fprintf(stderr, "Waiting for buffers\n");
619
620 radeonWaitForIdleLocked(&rmesa->radeon);
621 ret = drmDMA(fd, &dma);
622
623 if (ret != 0) {
624 UNLOCK_HARDWARE(&rmesa->radeon);
625 fprintf(stderr, "Error: Could not get dma buffer... exiting\n");
626 exit(-1);
627 }
628 }
629
630 UNLOCK_HARDWARE(&rmesa->radeon);
631
632 if (RADEON_DEBUG & DEBUG_DMA)
633 fprintf(stderr, "Allocated buffer %d\n", index);
634
635 dmabuf = CALLOC_STRUCT(r300_dma_buffer);
636 dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];
637 dmabuf->refcount = 1;
638
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;
644 }
645
646 void r300ReleaseDmaRegion(r300ContextPtr rmesa,
647 struct r300_dma_region *region, const char *caller)
648 {
649 if (RADEON_DEBUG & DEBUG_IOCTL)
650 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
651
652 if (!region->buf)
653 return;
654
655 if (rmesa->dma.flush)
656 rmesa->dma.flush(rmesa);
657
658 if (--region->buf->refcount == 0) {
659 drm_radeon_cmd_header_t *cmd;
660
661 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
662 fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
663 region->buf->buf->idx);
664 cmd =
665 (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
666 sizeof(*cmd) / 4,
667 __FUNCTION__);
668 cmd->dma.cmd_type = R300_CMD_DMA_DISCARD;
669 cmd->dma.buf_idx = region->buf->buf->idx;
670
671 FREE(region->buf);
672 rmesa->dma.nr_released_bufs++;
673 }
674
675 region->buf = 0;
676 region->start = 0;
677 }
678
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)
681 */
682 void r300AllocDmaRegion(r300ContextPtr rmesa,
683 struct r300_dma_region *region,
684 int bytes, int alignment)
685 {
686 if (RADEON_DEBUG & DEBUG_IOCTL)
687 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
688
689 if (rmesa->dma.flush)
690 rmesa->dma.flush(rmesa);
691
692 if (region->buf)
693 r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
694
695 alignment--;
696 rmesa->dma.current.start = rmesa->dma.current.ptr =
697 (rmesa->dma.current.ptr + alignment) & ~alignment;
698
699 if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
700 r300RefillCurrentDmaRegion(rmesa);
701
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++;
708
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;
712
713 assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
714 }
715
716 /* Called via glXGetMemoryOffsetMESA() */
717 GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
718 const GLvoid * pointer)
719 {
720 GET_CURRENT_CONTEXT(ctx);
721 r300ContextPtr rmesa;
722 GLuint card_offset;
723
724 if (!ctx || !(rmesa = R300_CONTEXT(ctx))) {
725 fprintf(stderr, "%s: no context\n", __FUNCTION__);
726 return ~0;
727 }
728
729 if (!r300IsGartMemory(rmesa, pointer, 0))
730 return ~0;
731
732 if (rmesa->radeon.dri.drmMinor < 6)
733 return ~0;
734
735 card_offset = r300GartOffsetFromVirtual(rmesa, pointer);
736
737 return card_offset - rmesa->radeon.radeonScreen->gart_base;
738 }
739
740 GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
741 GLint size)
742 {
743 int offset =
744 (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
745 int valid = (size >= 0 && offset >= 0
746 && offset + size < rmesa->radeon.radeonScreen->gartTextures.size);
747
748 if (RADEON_DEBUG & DEBUG_IOCTL)
749 fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
750 valid);
751
752 return valid;
753 }
754
755 GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
756 {
757 int offset =
758 (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
759
760 //fprintf(stderr, "offset=%08x\n", offset);
761
762 if (offset < 0 || offset > rmesa->radeon.radeonScreen->gartTextures.size)
763 return ~0;
764 else
765 return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
766 }
767
768 void r300InitIoctlFuncs(struct dd_function_table *functions)
769 {
770 functions->Clear = r300Clear;
771 functions->Finish = radeonFinish;
772 functions->Flush = r300Flush;
773 }