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