2 /**************************************************************************
4 Copyright 2001 VA Linux Systems Inc., Fremont, California.
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
29 /* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c,v 1.5 2002/12/10 01:26:53 dawes Exp $ */
33 * Jeff Hartmann <jhartmann@2d3d.com>
34 * Graeme Fisher <graeme@2d3d.co.za>
35 * Abraham vd Merwe <abraham@2d3d.co.za>
37 * Heavily based on the I810 driver, which was written by:
38 * Keith Whitwell <keith@tungstengraphics.com>
49 #include "swrast/swrast.h"
53 #include "i830_screen.h"
56 #include "i830_context.h"
57 #include "i830_ioctl.h"
58 #include "i830_state.h"
59 #include "i830_debug.h"
63 static drmBufPtr
i830_get_buffer_ioctl( i830ContextPtr imesa
)
69 retcode
= drmCommandWriteRead(imesa
->driFd
,
73 if (dma
.granted
== 1 && retcode
== 0)
77 imesa
->sarea
->perf_boxes
|= I830_BOX_WAIT
;
78 retcode
= drmCommandNone(imesa
->driFd
, DRM_I830_FLUSH
);
83 buf
= &(imesa
->i830Screen
->bufs
->list
[dma
.request_idx
]);
84 buf
->idx
= dma
.request_idx
;
86 buf
->total
= dma
.request_size
;
87 buf
->address
= (drmAddress
)dma
.virtual;
92 static void i830ClearDrawQuad(i830ContextPtr imesa
, float left
,
94 float bottom
, float top
, GLubyte red
,
95 GLubyte green
, GLubyte blue
, GLubyte alpha
)
97 GLuint
*vb
= i830AllocDmaLowLocked( imesa
, 128 );
103 /* initial vertex, left bottom */
108 tmp
.v
.color
.red
= red
;
109 tmp
.v
.color
.green
= green
;
110 tmp
.v
.color
.blue
= blue
;
111 tmp
.v
.color
.alpha
= alpha
;
112 tmp
.v
.specular
.red
= 0;
113 tmp
.v
.specular
.green
= 0;
114 tmp
.v
.specular
.blue
= 0;
115 tmp
.v
.specular
.alpha
= 0;
118 for (i
= 0 ; i
< 8 ; i
++)
124 for (i
= 0 ; i
< 8 ; i
++)
130 for (i
= 0 ; i
< 8 ; i
++)
136 for (i
= 0 ; i
< 8 ; i
++)
140 static void i830ClearWithTris(GLcontext
*ctx
, GLbitfield mask
,
142 GLint cx
, GLint cy
, GLint cw
, GLint ch
)
144 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
145 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
146 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
147 I830SAREAPtr sarea
= imesa
->sarea
;
148 GLuint old_vertex_prim
;
152 if (I830_DEBUG
& DEBUG_IOCTL
)
153 fprintf(stderr
, "Clearing with triangles\n");
155 old_dirty
= imesa
->dirty
& ~I830_UPLOAD_CLIPRECTS
;
156 /* Discard all the dirty flags except the cliprect one, reset later */
157 imesa
->dirty
&= I830_UPLOAD_CLIPRECTS
;
174 if (x1
> i830Screen
->width
-1) x1
= i830Screen
->width
-1;
175 if (y1
> i830Screen
->height
-1) y1
= i830Screen
->height
-1;
177 LOCK_HARDWARE(imesa
);
178 memcpy(sarea
->ContextState
,
180 sizeof(imesa
->Setup
) );
181 memcpy(sarea
->BufferState
,
183 sizeof(imesa
->BufferSetup
) );
184 sarea
->StippleState
[I830_STPREG_ST1
] = 0;
186 old_vertex_prim
= imesa
->hw_primitive
;
187 imesa
->hw_primitive
= PRIM3D_TRIFAN
;
189 if(mask
& DD_FRONT_LEFT_BIT
) {
190 GLuint tmp
= sarea
->ContextState
[I830_CTXREG_ENABLES_2
];
192 sarea
->dirty
|= (I830_UPLOAD_CTX
| I830_UPLOAD_BUFFERS
|
193 I830_UPLOAD_TEXBLEND0
);
195 sarea
->TexBlendState
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
197 ENABLE_TEXOUTPUT_WRT_SEL
|
198 TEXOP_OUTPUT_CURRENT
|
199 DISABLE_TEX_CNTRL_STAGE
|
204 sarea
->TexBlendState
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
206 ENABLE_TEXOUTPUT_WRT_SEL
|
207 TEXOP_OUTPUT_CURRENT
|
211 sarea
->TexBlendState
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
214 TEXBLENDARG_MODIFY_PARMS
|
215 TEXBLENDARG_CURRENT
);
216 sarea
->TexBlendState
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
219 TEXBLENDARG_MODIFY_PARMS
|
220 TEXBLENDARG_CURRENT
);
221 sarea
->TexBlendStateWordsUsed
[0] = 4;
223 tmp
&= ~(ENABLE_STENCIL_WRITE
| ENABLE_DEPTH_WRITE
);
224 tmp
|= (DISABLE_STENCIL_WRITE
|
225 DISABLE_DEPTH_WRITE
|
226 (imesa
->mask_red
<< WRITEMASK_RED_SHIFT
) |
227 (imesa
->mask_green
<< WRITEMASK_GREEN_SHIFT
) |
228 (imesa
->mask_blue
<< WRITEMASK_BLUE_SHIFT
) |
229 (imesa
->mask_alpha
<< WRITEMASK_ALPHA_SHIFT
));
230 sarea
->ContextState
[I830_CTXREG_ENABLES_2
] = tmp
;
233 fprintf(stderr
, "fcdq : r_mask(%d) g_mask(%d) b_mask(%d) a_mask(%d)\n",
234 imesa
->mask_red
, imesa
->mask_green
, imesa
->mask_blue
,
237 sarea
->BufferState
[I830_DESTREG_CBUFADDR
] = i830Screen
->fbOffset
;
240 fprintf(stderr
, "fcdq : x0(%d) x1(%d) y0(%d) y1(%d)\n"
241 "r(0x%x) g(0x%x) b(0x%x) a(0x%x)\n",
242 x0
, x1
, y0
, y1
, imesa
->clear_red
, imesa
->clear_green
,
243 imesa
->clear_blue
, imesa
->clear_alpha
);
245 i830ClearDrawQuad(imesa
, (float)x0
, (float)x1
, (float)y0
, (float)y1
,
246 imesa
->clear_red
, imesa
->clear_green
,
247 imesa
->clear_blue
, imesa
->clear_alpha
);
248 i830FlushPrimsLocked( imesa
);
251 if(mask
& DD_BACK_LEFT_BIT
) {
252 GLuint tmp
= sarea
->ContextState
[I830_CTXREG_ENABLES_2
];
254 sarea
->dirty
|= (I830_UPLOAD_CTX
| I830_UPLOAD_BUFFERS
|
255 I830_UPLOAD_TEXBLEND0
);
257 sarea
->TexBlendState
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
259 ENABLE_TEXOUTPUT_WRT_SEL
|
260 TEXOP_OUTPUT_CURRENT
|
261 DISABLE_TEX_CNTRL_STAGE
|
266 sarea
->TexBlendState
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
268 ENABLE_TEXOUTPUT_WRT_SEL
|
269 TEXOP_OUTPUT_CURRENT
|
273 sarea
->TexBlendState
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
276 TEXBLENDARG_MODIFY_PARMS
|
277 TEXBLENDARG_CURRENT
);
278 sarea
->TexBlendState
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
281 TEXBLENDARG_MODIFY_PARMS
|
282 TEXBLENDARG_CURRENT
);
283 sarea
->TexBlendStateWordsUsed
[0] = 4;
285 tmp
&= ~(ENABLE_STENCIL_WRITE
| ENABLE_DEPTH_WRITE
);
286 tmp
|= (DISABLE_STENCIL_WRITE
|
287 DISABLE_DEPTH_WRITE
|
288 (imesa
->mask_red
<< WRITEMASK_RED_SHIFT
) |
289 (imesa
->mask_green
<< WRITEMASK_GREEN_SHIFT
) |
290 (imesa
->mask_blue
<< WRITEMASK_BLUE_SHIFT
) |
291 (imesa
->mask_alpha
<< WRITEMASK_ALPHA_SHIFT
));
294 fprintf(stderr
, "bcdq : r_mask(%d) g_mask(%d) b_mask(%d) a_mask(%d)\n",
295 imesa
->mask_red
, imesa
->mask_green
, imesa
->mask_blue
,
298 sarea
->ContextState
[I830_CTXREG_ENABLES_2
] = tmp
;
300 sarea
->BufferState
[I830_DESTREG_CBUFADDR
] = i830Screen
->backOffset
;
303 fprintf(stderr
, "bcdq : x0(%d) x1(%d) y0(%d) y1(%d)\n"
304 "r(0x%x) g(0x%x) b(0x%x) a(0x%x)\n",
305 x0
, x1
, y0
, y1
, imesa
->clear_red
, imesa
->clear_green
,
306 imesa
->clear_blue
, imesa
->clear_alpha
);
308 i830ClearDrawQuad(imesa
, (float)x0
, (float)x1
, (float)y0
, (float)y1
,
309 imesa
->clear_red
, imesa
->clear_green
,
310 imesa
->clear_blue
, imesa
->clear_alpha
);
311 i830FlushPrimsLocked( imesa
);
314 if(mask
& DD_STENCIL_BIT
) {
315 GLuint s_mask
= ctx
->Stencil
.WriteMask
[0];
317 sarea
->dirty
|= (I830_UPLOAD_CTX
| I830_UPLOAD_BUFFERS
|
318 I830_UPLOAD_TEXBLEND0
);
320 sarea
->TexBlendState
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
322 ENABLE_TEXOUTPUT_WRT_SEL
|
323 TEXOP_OUTPUT_CURRENT
|
324 DISABLE_TEX_CNTRL_STAGE
|
329 sarea
->TexBlendState
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
331 ENABLE_TEXOUTPUT_WRT_SEL
|
332 TEXOP_OUTPUT_CURRENT
|
336 sarea
->TexBlendState
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
339 TEXBLENDARG_MODIFY_PARMS
|
340 TEXBLENDARG_CURRENT
);
341 sarea
->TexBlendState
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
344 TEXBLENDARG_MODIFY_PARMS
|
345 TEXBLENDARG_CURRENT
);
346 sarea
->TexBlendStateWordsUsed
[0] = 4;
348 sarea
->ContextState
[I830_CTXREG_ENABLES_1
] |= (ENABLE_STENCIL_TEST
|
351 sarea
->ContextState
[I830_CTXREG_ENABLES_2
] &= ~(ENABLE_STENCIL_WRITE
|
355 sarea
->ContextState
[I830_CTXREG_ENABLES_2
] |=
356 (ENABLE_STENCIL_WRITE
|
357 DISABLE_DEPTH_WRITE
|
358 (1 << WRITEMASK_RED_SHIFT
) |
359 (1 << WRITEMASK_GREEN_SHIFT
) |
360 (1 << WRITEMASK_BLUE_SHIFT
) |
361 (1 << WRITEMASK_ALPHA_SHIFT
) |
364 sarea
->ContextState
[I830_CTXREG_STATE4
] &=
365 ~MODE4_ENABLE_STENCIL_WRITE_MASK
;
367 sarea
->ContextState
[I830_CTXREG_STATE4
] |=
368 (ENABLE_STENCIL_WRITE_MASK
|
369 STENCIL_WRITE_MASK(s_mask
));
371 sarea
->ContextState
[I830_CTXREG_STENCILTST
] &=
373 STENCIL_REF_VALUE_MASK
|
374 ENABLE_STENCIL_TEST_FUNC_MASK
);
376 sarea
->ContextState
[I830_CTXREG_STENCILTST
] |=
377 (ENABLE_STENCIL_PARMS
|
378 ENABLE_STENCIL_REF_VALUE
|
379 ENABLE_STENCIL_TEST_FUNC
|
380 STENCIL_FAIL_OP(STENCILOP_REPLACE
) |
381 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE
) |
382 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE
) |
383 STENCIL_REF_VALUE((ctx
->Stencil
.Clear
& 0xff)) |
384 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS
));
387 fprintf(stderr
, "Enables_1 (0x%x) Enables_2 (0x%x) StenTst (0x%x)\n"
389 sarea
->ContextState
[I830_CTXREG_ENABLES_1
],
390 sarea
->ContextState
[I830_CTXREG_ENABLES_2
],
391 sarea
->ContextState
[I830_CTXREG_STENCILTST
],
392 sarea
->ContextState
[I830_CTXREG_STATE4
]);
394 sarea
->BufferState
[I830_DESTREG_CBUFADDR
] = i830Screen
->fbOffset
;
396 i830ClearDrawQuad(imesa
, (float)x0
, (float)x1
, (float)y0
, (float)y1
,
398 i830FlushPrimsLocked( imesa
);
401 UNLOCK_HARDWARE(imesa
);
402 imesa
->dirty
= old_dirty
;
403 imesa
->dirty
|= (I830_UPLOAD_CTX
|
404 I830_UPLOAD_BUFFERS
|
405 I830_UPLOAD_TEXBLEND0
);
407 imesa
->hw_primitive
= old_vertex_prim
;
410 static void i830Clear(GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
411 GLint cx1
, GLint cy1
, GLint cw
, GLint ch
)
413 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
414 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
415 const GLuint colorMask
= *((GLuint
*) &ctx
->Color
.ColorMask
);
417 GLbitfield tri_mask
= 0;
421 /* flip top to bottom */
422 cy
= dPriv
->h
-cy1
-ch
;
423 cx
= cx1
+ imesa
->drawX
;
426 if(0) fprintf(stderr
, "\nClearColor : 0x%08x\n", imesa
->ClearColor
);
429 clear
.clear_color
= imesa
->ClearColor
;
430 clear
.clear_depth
= 0;
431 clear
.clear_colormask
= 0;
432 clear
.clear_depthmask
= 0;
434 I830_FIREVERTICES( imesa
);
436 if (mask
& DD_FRONT_LEFT_BIT
) {
437 if(colorMask
== ~0) {
438 clear
.flags
|= I830_FRONT
;
440 tri_mask
|= DD_FRONT_LEFT_BIT
;
442 mask
&= ~DD_FRONT_LEFT_BIT
;
445 if (mask
& DD_BACK_LEFT_BIT
) {
446 if(colorMask
== ~0) {
447 clear
.flags
|= I830_BACK
;
449 tri_mask
|= DD_BACK_LEFT_BIT
;
451 mask
&= ~DD_BACK_LEFT_BIT
;
454 if (mask
& DD_DEPTH_BIT
) {
455 clear
.flags
|= I830_DEPTH
;
456 clear
.clear_depthmask
= imesa
->depth_clear_mask
;
457 clear
.clear_depth
= (GLuint
)(ctx
->Depth
.Clear
* imesa
->ClearDepth
);
458 mask
&= ~DD_DEPTH_BIT
;
461 if((mask
& DD_STENCIL_BIT
) && imesa
->hw_stencil
) {
462 if (ctx
->Stencil
.WriteMask
[0] != 0xff) {
463 tri_mask
|= DD_STENCIL_BIT
;
465 clear
.flags
|= I830_DEPTH
;
466 clear
.clear_depthmask
|= imesa
->stencil_clear_mask
;
467 clear
.clear_depth
|= (ctx
->Stencil
.Clear
& 0xff) << 24;
469 mask
&= ~DD_STENCIL_BIT
;
472 /* First check for clears that need to happen with triangles */
474 i830ClearWithTris(ctx
, tri_mask
, all
, cx
, cy
, cw
, ch
);
478 LOCK_HARDWARE( imesa
);
480 for (i
= 0 ; i
< imesa
->numClipRects
; )
482 int nr
= MIN2(i
+ I830_NR_SAREA_CLIPRECTS
, imesa
->numClipRects
);
483 XF86DRIClipRectRec
*box
= imesa
->pClipRects
;
484 drm_clip_rect_t
*b
= (drm_clip_rect_t
*)imesa
->sarea
->boxes
;
488 for ( ; i
< nr
; i
++) {
491 GLint w
= box
[i
].x2
- x
;
492 GLint h
= box
[i
].y2
- y
;
494 if (x
< cx
) w
-= cx
- x
, x
= cx
;
495 if (y
< cy
) h
-= cy
- y
, y
= cy
;
496 if (x
+ w
> cx
+ cw
) w
= cx
+ cw
- x
;
497 if (y
+ h
> cy
+ ch
) h
= cy
+ ch
- y
;
498 if (w
<= 0) continue;
499 if (h
<= 0) continue;
509 for ( ; i
< nr
; i
++) {
510 *b
++ = *(drm_clip_rect_t
*)&box
[i
];
515 imesa
->sarea
->nbox
= n
;
516 drmCommandWrite(imesa
->driFd
, DRM_I830_CLEAR
,
517 &clear
, sizeof(drmI830Clear
));
520 UNLOCK_HARDWARE( imesa
);
521 imesa
->upload_cliprects
= GL_TRUE
;
525 _swrast_Clear( ctx
, mask
, all
, cx1
, cy1
, cw
, ch
);
531 * Copy the back buffer to the front buffer.
533 void i830CopyBuffer( const __DRIdrawablePrivate
*dPriv
)
535 i830ContextPtr imesa
;
536 XF86DRIClipRectPtr pbox
;
540 assert(dPriv
->driContextPriv
);
541 assert(dPriv
->driContextPriv
->driverPrivate
);
543 imesa
= (i830ContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
545 I830_FIREVERTICES( imesa
);
546 LOCK_HARDWARE( imesa
);
548 imesa
->sarea
->perf_boxes
|= imesa
->perf_boxes
;
549 imesa
->perf_boxes
= 0;
551 pbox
= dPriv
->pClipRects
;
552 nbox
= dPriv
->numClipRects
;
554 for (i
= 0 ; i
< nbox
; )
556 int nr
= MIN2(i
+ I830_NR_SAREA_CLIPRECTS
, dPriv
->numClipRects
);
557 XF86DRIClipRectRec
*b
= (XF86DRIClipRectRec
*)imesa
->sarea
->boxes
;
559 imesa
->sarea
->nbox
= nr
- i
;
561 for ( ; i
< nr
; i
++)
563 drmCommandNone(imesa
->driFd
, DRM_I830_SWAP
);
566 tmp
= GET_ENQUEUE_AGE(imesa
);
567 UNLOCK_HARDWARE( imesa
);
569 /* multiarb will suck the life out of the server without this throttle:
571 if (GET_DISPATCH_AGE(imesa
) < imesa
->lastSwap
) {
572 i830WaitAge(imesa
, imesa
->lastSwap
);
575 imesa
->lastSwap
= tmp
;
576 imesa
->upload_cliprects
= GL_TRUE
;
579 /* Flip the front & back buffes
581 void i830PageFlip( const __DRIdrawablePrivate
*dPriv
)
584 i830ContextPtr imesa
;
587 if (I830_DEBUG
& DEBUG_IOCTL
)
588 fprintf(stderr
, "%s\n", __FUNCTION__
);
591 assert(dPriv
->driContextPriv
);
592 assert(dPriv
->driContextPriv
->driverPrivate
);
594 imesa
= (i830ContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
596 I830_FIREVERTICES( imesa
);
597 LOCK_HARDWARE( imesa
);
599 imesa
->sarea
->perf_boxes
|= imesa
->perf_boxes
;
600 imesa
->perf_boxes
= 0;
602 if (dPriv
->pClipRects
) {
603 *(XF86DRIClipRectRec
*)imesa
->sarea
->boxes
= dPriv
->pClipRects
[0];
604 imesa
->sarea
->nbox
= 1;
607 ret
= drmCommandNone(imesa
->driFd
, DRM_I830_FLIP
);
609 fprintf(stderr
, "%s: %d\n", __FUNCTION__
, ret
);
610 UNLOCK_HARDWARE( imesa
);
614 tmp
= GET_ENQUEUE_AGE(imesa
);
615 UNLOCK_HARDWARE( imesa
);
617 /* multiarb will suck the life out of the server without this throttle:
619 if (GET_DISPATCH_AGE(imesa
) < imesa
->lastSwap
) {
620 i830WaitAge(imesa
, imesa
->lastSwap
);
623 i830SetDrawBuffer( imesa
->glCtx
, imesa
->glCtx
->Color
.DriverDrawBuffer
);
624 imesa
->upload_cliprects
= GL_TRUE
;
625 imesa
->lastSwap
= tmp
;
629 /* This waits for *everybody* to finish rendering -- overkill.
631 void i830DmaFinish( i830ContextPtr imesa
)
633 I830_FIREVERTICES( imesa
);
634 LOCK_HARDWARE_QUIESCENT( imesa
);
635 UNLOCK_HARDWARE( imesa
);
638 void i830RegetLockQuiescent( i830ContextPtr imesa
)
640 drmUnlock(imesa
->driFd
, imesa
->hHWContext
);
641 i830GetLock( imesa
, DRM_LOCK_QUIESCENT
);
644 void i830WaitAgeLocked( i830ContextPtr imesa
, int age
)
648 drmCommandNone(imesa
->driFd
, DRM_I830_GETAGE
);
649 if (GET_DISPATCH_AGE(imesa
) >= age
) return;
650 imesa
->sarea
->perf_boxes
|= I830_BOX_WAIT
;
651 UNLOCK_HARDWARE( imesa
);
652 if (I830_DEBUG
& DEBUG_SLEEP
) fprintf(stderr
, ".");
654 LOCK_HARDWARE( imesa
);
656 /* If that didn't work, just do a flush:
658 drmCommandNone(imesa
->driFd
, DRM_I830_FLUSH
);
661 void i830WaitAge( i830ContextPtr imesa
, int age
)
664 if (GET_DISPATCH_AGE(imesa
) >= age
) return;
667 drmCommandNone(imesa
->driFd
, DRM_I830_GETAGE
);
668 if (GET_DISPATCH_AGE(imesa
) >= age
) return;
669 imesa
->perf_boxes
|= I830_BOX_WAIT
;
671 if (imesa
->do_irqs
) {
676 ie
.irq_seq
= &iw
.irq_seq
;
678 LOCK_HARDWARE( imesa
);
679 ret
= drmCommandWriteRead( imesa
->driFd
, DRM_I830_IRQ_EMIT
, &ie
, sizeof(ie
) );
681 fprintf( stderr
, "%s: drmI830IrqEmit: %d\n", __FUNCTION__
, ret
);
684 UNLOCK_HARDWARE(imesa
);
686 ret
= drmCommandWrite( imesa
->driFd
, DRM_I830_IRQ_WAIT
, &iw
, sizeof(iw
) );
688 fprintf( stderr
, "%s: drmI830IrqWait: %d\n", __FUNCTION__
, ret
);
692 if (++i
> 5000) usleep(1);
697 static void age_imesa( i830ContextPtr imesa
, int age
)
699 if (imesa
->CurrentTexObj
[0]) imesa
->CurrentTexObj
[0]->base
.timestamp
= age
;
700 if (imesa
->CurrentTexObj
[1]) imesa
->CurrentTexObj
[1]->base
.timestamp
= age
;
703 void i830FlushPrimsLocked( i830ContextPtr imesa
)
705 XF86DRIClipRectPtr pbox
= (XF86DRIClipRectPtr
)imesa
->pClipRects
;
706 int nbox
= imesa
->numClipRects
;
707 drmBufPtr buffer
= imesa
->vertex_buffer
;
708 I830SAREAPtr sarea
= imesa
->sarea
;
709 drmI830Vertex vertex
;
712 if (I830_DEBUG
& DEBUG_IOCTL
)
713 fprintf(stderr
, "%s dirty: %08x\n", __FUNCTION__
, imesa
->dirty
);
716 vertex
.idx
= buffer
->idx
;
717 vertex
.used
= imesa
->vertex_low
;
719 sarea
->vertex_prim
= imesa
->hw_primitive
;
723 imesa
->vertex_buffer
= 0;
724 imesa
->vertex_addr
= 0;
725 imesa
->vertex_low
= 0;
726 imesa
->vertex_high
= 0;
727 imesa
->vertex_last_prim
= 0;
730 if (I830_DEBUG
& DEBUG_SANITY
)
731 i830EmitHwStateLockedDebug(imesa
);
733 i830EmitHwStateLocked(imesa
);
736 if (I830_DEBUG
& DEBUG_IOCTL
)
737 fprintf(stderr
,"%s: Vertex idx %d used %d discard %d\n",
738 __FUNCTION__
, vertex
.idx
, vertex
.used
, vertex
.discard
);
743 if (drmCommandWrite (imesa
->driFd
, DRM_I830_VERTEX
,
744 &vertex
, sizeof(drmI830Vertex
))) {
745 fprintf(stderr
, "DRM_I830_VERTEX: %d\n", -errno
);
746 UNLOCK_HARDWARE(imesa
);
752 for (i
= 0 ; i
< nbox
; i
= nr
) {
753 XF86DRIClipRectPtr b
= sarea
->boxes
;
756 nr
= MIN2(i
+ I830_NR_SAREA_CLIPRECTS
, nbox
);
757 sarea
->nbox
= nr
- i
;
759 for ( j
= i
; j
< nr
; j
++) {
763 /* Finished with the buffer?
768 /* Do a bunch of sanity checks on the vertices sent to the hardware */
769 if (I830_DEBUG
& DEBUG_SANITY
) {
770 i830VertexSanity(imesa
, vertex
);
772 for ( j
= 0 ; j
< sarea
->nbox
; j
++) {
773 fprintf(stderr
, "box %d/%d %d,%d %d,%d\n",
774 j
, sarea
->nbox
, b
[j
].x1
, b
[j
].y1
, b
[j
].x2
, b
[j
].y2
);
778 drmCommandWrite (imesa
->driFd
, DRM_I830_VERTEX
,
779 &vertex
, sizeof(drmI830Vertex
));
780 age_imesa(imesa
, imesa
->sarea
->last_enqueue
);
784 imesa
->upload_cliprects
= GL_FALSE
;
787 void i830FlushPrimsGetBufferLocked( i830ContextPtr imesa
)
789 if (imesa
->vertex_buffer
)
790 i830FlushPrimsLocked( imesa
);
791 imesa
->vertex_buffer
= i830_get_buffer_ioctl( imesa
);
792 imesa
->vertex_addr
= (char *)imesa
->vertex_buffer
->address
;
794 /* leave room for instruction header & footer:
796 imesa
->vertex_high
= imesa
->vertex_buffer
->total
- 4;
797 imesa
->vertex_low
= 4;
798 imesa
->vertex_last_prim
= imesa
->vertex_low
;
801 void i830FlushPrimsGetBuffer( i830ContextPtr imesa
)
803 LOCK_HARDWARE(imesa
);
804 i830FlushPrimsGetBufferLocked( imesa
);
805 UNLOCK_HARDWARE(imesa
);
809 void i830FlushPrims( i830ContextPtr imesa
)
811 if (imesa
->vertex_buffer
) {
812 LOCK_HARDWARE( imesa
);
813 i830FlushPrimsLocked( imesa
);
814 UNLOCK_HARDWARE( imesa
);
818 int i830_check_copy(int fd
)
820 return drmCommandNone(fd
, DRM_I830_DOCOPY
);
823 static void i830Flush( GLcontext
*ctx
)
825 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
826 I830_FIREVERTICES( imesa
);
829 static void i830Finish( GLcontext
*ctx
)
831 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
832 i830DmaFinish( imesa
);
835 void i830InitIoctlFuncs( struct dd_function_table
*functions
)
837 functions
->Flush
= i830Flush
;
838 functions
->Clear
= i830Clear
;
839 functions
->Finish
= i830Finish
;