Properly input stencil info contributed by Wladimir.
[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
55 #include "vblank.h"
56
57
58 #define CLEARBUFFER_COLOR 0x1
59 #define CLEARBUFFER_DEPTH 0x2
60
61 static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
62 {
63 GLcontext* ctx = r300->radeon.glCtx;
64 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
65 int i;
66 GLuint cboffset, cbpitch;
67 drm_r300_cmd_header_t* cmd;
68
69 if (RADEON_DEBUG & DEBUG_IOCTL)
70 fprintf(stderr, "%s: %s buffer (%i,%i %ix%i)\n",
71 __FUNCTION__, buffer ? "back" : "front",
72 dPriv->x, dPriv->y, dPriv->w, dPriv->h);
73
74 if (buffer) {
75 cboffset = r300->radeon.radeonScreen->backOffset;
76 cbpitch = r300->radeon.radeonScreen->backPitch;
77 } else {
78 cboffset = r300->radeon.radeonScreen->frontOffset;
79 cbpitch = r300->radeon.radeonScreen->frontPitch;
80 }
81
82 cboffset += r300->radeon.radeonScreen->fbLocation;
83
84 R300_STATECHANGE(r300, vir[0]);
85 ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
86 r300->hw.vir[0].cmd[1] = 0x21030003;
87
88 R300_STATECHANGE(r300, vir[1]);
89 ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
90 r300->hw.vir[1].cmd[1] = 0xF688F688;
91
92 R300_STATECHANGE(r300, vic);
93 r300->hw.vic.cmd[R300_VIC_CNTL_0] = 0x00000001;
94 r300->hw.vic.cmd[R300_VIC_CNTL_1] = 0x00000405;
95
96 R300_STATECHANGE(r300, vof);
97 r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
98 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
99 r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
100
101 R300_STATECHANGE(r300, txe);
102 r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
103
104 R300_STATECHANGE(r300, vpt);
105 r300->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(1.0);
106 r300->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(dPriv->x);
107 r300->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(1.0);
108 r300->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(dPriv->y);
109 r300->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(1.0);
110 r300->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(0.0);
111
112 R300_STATECHANGE(r300, at);
113 r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
114
115 R300_STATECHANGE(r300, bld);
116 r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
117 r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
118
119 R300_STATECHANGE(r300, cb);
120 r300->hw.cb.cmd[R300_CB_OFFSET] = cboffset;
121 r300->hw.cb.cmd[R300_CB_PITCH] = cbpitch | R300_COLOR_UNKNOWN_22_23;
122
123 R300_STATECHANGE(r300, unk221C);
124 r300->hw.unk221C.cmd[1] = R300_221C_CLEAR;
125
126 R300_STATECHANGE(r300, ps);
127 r300->hw.ps.cmd[R300_PS_POINTSIZE] =
128 ((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) |
129 ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT);
130
131 R300_STATECHANGE(r300, ri);
132 for(i = 1; i <= 8; ++i)
133 r300->hw.ri.cmd[i] = R300_RS_INTERP_USED;
134
135 R300_STATECHANGE(r300, rc);
136 /* The second constant is needed to get glxgears display anything .. */
137 r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
138 r300->hw.rc.cmd[2] = 0;
139
140 R300_STATECHANGE(r300, rr);
141 ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
142 r300->hw.rr.cmd[1] = 0x00004000;
143
144 R300_STATECHANGE(r300, cmk);
145 if (flags & CLEARBUFFER_COLOR) {
146 r300->hw.cmk.cmd[R300_CMK_COLORMASK] =
147 (ctx->Color.ColorMask[BCOMP] ? R300_COLORMASK0_B : 0) |
148 (ctx->Color.ColorMask[GCOMP] ? R300_COLORMASK0_G : 0) |
149 (ctx->Color.ColorMask[RCOMP] ? R300_COLORMASK0_R : 0) |
150 (ctx->Color.ColorMask[ACOMP] ? R300_COLORMASK0_A : 0);
151 } else {
152 r300->hw.cmk.cmd[R300_CMK_COLORMASK] = 0;
153 }
154
155 R300_STATECHANGE(r300, fp);
156 r300->hw.fp.cmd[R300_FP_CNTL0] = 0; /* 1 pass, no textures */
157 r300->hw.fp.cmd[R300_FP_CNTL1] = 0; /* no temporaries */
158 r300->hw.fp.cmd[R300_FP_CNTL2] = 0; /* no offset, one ALU instr */
159 r300->hw.fp.cmd[R300_FP_NODE0] = 0;
160 r300->hw.fp.cmd[R300_FP_NODE1] = 0;
161 r300->hw.fp.cmd[R300_FP_NODE2] = 0;
162 r300->hw.fp.cmd[R300_FP_NODE3] = R300_PFS_NODE_LAST_NODE;
163
164 R300_STATECHANGE(r300, fpi[0]);
165 R300_STATECHANGE(r300, fpi[1]);
166 R300_STATECHANGE(r300, fpi[2]);
167 R300_STATECHANGE(r300, fpi[3]);
168 ((drm_r300_cmd_header_t*)r300->hw.fpi[0].cmd)->unchecked_state.count = 1;
169 ((drm_r300_cmd_header_t*)r300->hw.fpi[1].cmd)->unchecked_state.count = 1;
170 ((drm_r300_cmd_header_t*)r300->hw.fpi[2].cmd)->unchecked_state.count = 1;
171 ((drm_r300_cmd_header_t*)r300->hw.fpi[3].cmd)->unchecked_state.count = 1;
172
173 /* MOV o0, t0 */
174 r300->hw.fpi[0].cmd[1] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
175 r300->hw.fpi[1].cmd[1] = FP_SELC(0,NO,XYZ,FP_TMP(0),0,0);
176 r300->hw.fpi[2].cmd[1] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
177 r300->hw.fpi[3].cmd[1] = FP_SELA(0,NO,W,FP_TMP(0),0,0);
178
179 R300_STATECHANGE(r300, pvs);
180 r300->hw.pvs.cmd[R300_PVS_CNTL_1] =
181 (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
182 (0 << R300_PVS_CNTL_1_UNKNOWN_SHIFT) |
183 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
184 r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0; /* no parameters */
185 r300->hw.pvs.cmd[R300_PVS_CNTL_3] =
186 (1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
187
188 R300_STATECHANGE(r300, vpi);
189 ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->unchecked_state.count = 8;
190
191 /* MOV o0, i0; */
192 r300->hw.vpi.cmd[1] = VP_OUT(ADD,OUT,0,XYZW);
193 r300->hw.vpi.cmd[2] = VP_IN(IN,0);
194 r300->hw.vpi.cmd[3] = VP_ZERO();
195 r300->hw.vpi.cmd[4] = 0;
196
197 /* MOV o1, i1; */
198 r300->hw.vpi.cmd[5] = VP_OUT(ADD,OUT,1,XYZW);
199 r300->hw.vpi.cmd[6] = VP_IN(IN,1);
200 r300->hw.vpi.cmd[7] = VP_ZERO();
201 r300->hw.vpi.cmd[8] = 0;
202
203 R300_STATECHANGE(r300, zs);
204 if (flags & CLEARBUFFER_DEPTH) {
205 r300->hw.zs.cmd[R300_ZS_CNTL_0] = 0x6; // test and write
206 r300->hw.zs.cmd[R300_ZS_CNTL_1] = (R300_ZS_ALWAYS<<R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
207 /*
208 R300_STATECHANGE(r300, zb);
209 r300->hw.zb.cmd[R300_ZB_OFFSET] =
210 1024*4*300 +
211 r300->radeon.radeonScreen->frontOffset +
212 r300->radeon.radeonScreen->fbLocation;
213 r300->hw.zb.cmd[R300_ZB_PITCH] =
214 r300->radeon.radeonScreen->depthPitch;
215 */
216 } else {
217 r300->hw.zs.cmd[R300_ZS_CNTL_0] = 0; // disable
218 r300->hw.zs.cmd[R300_ZS_CNTL_1] = 0;
219 }
220
221 /* Make sure we have enough space */
222 r300EnsureCmdBufSpace(r300, r300->hw.max_state_size + 9, __FUNCTION__);
223
224 r300EmitState(r300);
225
226 cmd = (drm_r300_cmd_header_t*)r300AllocCmdBuf(r300, 9, __FUNCTION__);
227 cmd[0].packet3.cmd_type = R300_CMD_PACKET3;
228 cmd[0].packet3.packet = R300_CMD_PACKET3_CLEAR;
229 cmd[1].u = r300PackFloat32(dPriv->w / 2.0);
230 cmd[2].u = r300PackFloat32(dPriv->h / 2.0);
231 cmd[3].u = r300PackFloat32(ctx->Depth.Clear);
232 cmd[4].u = r300PackFloat32(1.0);
233 cmd[5].u = r300PackFloat32(ctx->Color.ClearColor[0]);
234 cmd[6].u = r300PackFloat32(ctx->Color.ClearColor[1]);
235 cmd[7].u = r300PackFloat32(ctx->Color.ClearColor[2]);
236 cmd[8].u = r300PackFloat32(ctx->Color.ClearColor[3]);
237 }
238
239
240 /**
241 * Buffer clear
242 */
243 static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
244 GLint cx, GLint cy, GLint cw, GLint ch)
245 {
246 r300ContextPtr r300 = R300_CONTEXT(ctx);
247 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
248 int flags = 0;
249 int bits = 0;
250 int swapped;
251
252 if (RADEON_DEBUG & DEBUG_IOCTL)
253 fprintf(stderr, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n",
254 __FUNCTION__, all, cx, cy, cw, ch);
255
256 {
257 LOCK_HARDWARE(&r300->radeon);
258 UNLOCK_HARDWARE(&r300->radeon);
259 if (dPriv->numClipRects == 0)
260 return;
261 }
262
263 if (mask & DD_FRONT_LEFT_BIT) {
264 flags |= DD_FRONT_LEFT_BIT;
265 mask &= ~DD_FRONT_LEFT_BIT;
266 }
267
268 if (mask & DD_BACK_LEFT_BIT) {
269 flags |= DD_BACK_LEFT_BIT;
270 mask &= ~DD_BACK_LEFT_BIT;
271 }
272
273 if (mask & DD_DEPTH_BIT) {
274 bits |= CLEARBUFFER_DEPTH;
275 mask &= ~DD_DEPTH_BIT;
276 }
277
278 if (mask) {
279 if (RADEON_DEBUG & DEBUG_FALLBACKS)
280 fprintf(stderr, "%s: swrast clear, mask: %x\n",
281 __FUNCTION__, mask);
282 _swrast_Clear(ctx, mask, all, cx, cy, cw, ch);
283 }
284
285 swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1);
286
287 if (flags & DD_FRONT_LEFT_BIT) {
288 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);
289 bits = 0;
290 }
291
292 if (flags & DD_BACK_LEFT_BIT) {
293 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);
294 bits = 0;
295 }
296
297 if (bits)
298 r300ClearBuffer(r300, bits, 0);
299
300 /* Recalculate the hardware state. This could be done more efficiently,
301 * but do keep it like this for now.
302 */
303 r300ResetHwState(r300);
304 /* r300ClearBuffer has trampled all over the hardware state.. */
305 r300->hw.all_dirty=GL_TRUE;
306 }
307
308 void r300Flush(GLcontext * ctx)
309 {
310 r300ContextPtr r300 = R300_CONTEXT(ctx);
311
312 if (RADEON_DEBUG & DEBUG_IOCTL)
313 fprintf(stderr, "%s\n", __FUNCTION__);
314
315 if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
316 r300FlushCmdBuf(r300, __FUNCTION__);
317 }
318
319 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
320 {
321 struct r200_dma_buffer *dmabuf;
322 int fd = rmesa->radeon.dri.fd;
323 int index = 0;
324 int size = 0;
325 drmDMAReq dma;
326 int ret;
327
328 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
329 fprintf(stderr, "%s\n", __FUNCTION__);
330
331 if (rmesa->dma.flush) {
332 rmesa->dma.flush(rmesa);
333 }
334
335 if (rmesa->dma.current.buf)
336 r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
337
338 if (rmesa->dma.nr_released_bufs > 4)
339 r300FlushCmdBuf(rmesa, __FUNCTION__);
340
341 dma.context = rmesa->radeon.dri.hwContext;
342 dma.send_count = 0;
343 dma.send_list = NULL;
344 dma.send_sizes = NULL;
345 dma.flags = 0;
346 dma.request_count = 1;
347 dma.request_size = RADEON_BUFFER_SIZE;
348 dma.request_list = &index;
349 dma.request_sizes = &size;
350 dma.granted_count = 0;
351
352 LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
353
354 while (1) {
355 ret = drmDMA(fd, &dma);
356 if (ret == 0)
357 break;
358
359 if (rmesa->dma.nr_released_bufs) {
360 r200FlushCmdBufLocked(rmesa, __FUNCTION__);
361 }
362
363 if (rmesa->radeon.do_usleeps) {
364 UNLOCK_HARDWARE(&rmesa->radeon);
365 DO_USLEEP(1);
366 LOCK_HARDWARE(&rmesa->radeon);
367 }
368 }
369
370 UNLOCK_HARDWARE(&rmesa->radeon);
371
372 if (RADEON_DEBUG & DEBUG_DMA)
373 fprintf(stderr, "Allocated buffer %d\n", index);
374
375 dmabuf = CALLOC_STRUCT(r300_dma_buffer);
376 dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];
377 dmabuf->refcount = 1;
378
379 rmesa->dma.current.buf = dmabuf;
380 rmesa->dma.current.address = dmabuf->buf->address;
381 rmesa->dma.current.end = dmabuf->buf->total;
382 rmesa->dma.current.start = 0;
383 rmesa->dma.current.ptr = 0;
384 }
385
386 void r300ReleaseDmaRegion(r300ContextPtr rmesa,
387 struct r300_dma_region *region, const char *caller)
388 {
389 if (RADEON_DEBUG & DEBUG_IOCTL)
390 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
391
392 if (!region->buf)
393 return;
394
395 if (rmesa->dma.flush)
396 rmesa->dma.flush(rmesa);
397
398 if (--region->buf->refcount == 0) {
399 drm_radeon_cmd_header_t *cmd;
400
401 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
402 fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
403 region->buf->buf->idx);
404
405 cmd =
406 (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
407 sizeof(*cmd),
408 __FUNCTION__);
409 cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD;
410 cmd->dma.buf_idx = region->buf->buf->idx;
411 FREE(region->buf);
412 rmesa->dma.nr_released_bufs++;
413 }
414
415 region->buf = 0;
416 region->start = 0;
417 }
418
419 /* Allocates a region from rmesa->dma.current. If there isn't enough
420 * space in current, grab a new buffer (and discard what was left of current)
421 */
422 void r300AllocDmaRegion(r300ContextPtr rmesa,
423 struct r300_dma_region *region,
424 int bytes, int alignment)
425 {
426 if (RADEON_DEBUG & DEBUG_IOCTL)
427 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
428
429 if (rmesa->dma.flush)
430 rmesa->dma.flush(rmesa);
431
432 if (region->buf)
433 r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
434
435 alignment--;
436 rmesa->dma.current.start = rmesa->dma.current.ptr =
437 (rmesa->dma.current.ptr + alignment) & ~alignment;
438
439 if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
440 r300RefillCurrentDmaRegion(rmesa);
441
442 region->start = rmesa->dma.current.start;
443 region->ptr = rmesa->dma.current.start;
444 region->end = rmesa->dma.current.start + bytes;
445 region->address = rmesa->dma.current.address;
446 region->buf = rmesa->dma.current.buf;
447 region->buf->refcount++;
448
449 rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
450 rmesa->dma.current.start =
451 rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
452
453 assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
454 }
455
456 /* Called via glXGetMemoryOffsetMESA() */
457 GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
458 const GLvoid * pointer)
459 {
460 GET_CURRENT_CONTEXT(ctx);
461 r300ContextPtr rmesa;
462 GLuint card_offset;
463
464 if (!ctx || !(rmesa = R300_CONTEXT(ctx))) {
465 fprintf(stderr, "%s: no context\n", __FUNCTION__);
466 return ~0;
467 }
468
469 if (!r300IsGartMemory(rmesa, pointer, 0))
470 return ~0;
471
472 if (rmesa->radeon.dri.drmMinor < 6)
473 return ~0;
474
475 card_offset = r300GartOffsetFromVirtual(rmesa, pointer);
476
477 return card_offset - rmesa->radeon.radeonScreen->gart_base;
478 }
479
480 GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
481 GLint size)
482 {
483 int offset =
484 (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
485 int valid = (size >= 0 && offset >= 0
486 && offset + size < rmesa->radeon.radeonScreen->gartTextures.size);
487
488 if (RADEON_DEBUG & DEBUG_IOCTL)
489 fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
490 valid);
491
492 return valid;
493 }
494
495 GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
496 {
497 int offset =
498 (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
499
500 fprintf(stderr, "offset=%08x\n", offset);
501
502 if (offset < 0 || offset > rmesa->radeon.radeonScreen->gartTextures.size)
503 return ~0;
504 else
505 return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
506 }
507
508 void r300InitIoctlFuncs(struct dd_function_table *functions)
509 {
510 functions->Clear = r300Clear;
511 functions->Finish = radeonFinish;
512 functions->Flush = r300Flush;
513 }