Don't index box by the box's index within numClipRects; just dereference it.
[mesa.git] / src / mesa / drivers / dri / i915 / intel_batchbuffer.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include <stdio.h>
30 #include <errno.h>
31
32 #include "mtypes.h"
33 #include "context.h"
34 #include "enums.h"
35 #include "vblank.h"
36
37 #include "intel_reg.h"
38 #include "intel_batchbuffer.h"
39 #include "intel_context.h"
40
41
42
43
44 /* ================================================================
45 * Performance monitoring functions
46 */
47
48 static void intel_fill_box( intelContextPtr intel,
49 GLshort x, GLshort y,
50 GLshort w, GLshort h,
51 GLubyte r, GLubyte g, GLubyte b )
52 {
53 x += intel->drawX;
54 y += intel->drawY;
55
56 if (x >= 0 && y >= 0 &&
57 x+w < intel->intelScreen->width &&
58 y+h < intel->intelScreen->height)
59 intelEmitFillBlitLocked( intel,
60 intel->intelScreen->cpp,
61 intel->intelScreen->back.pitch,
62 intel->intelScreen->back.offset,
63 x, y, w, h,
64 INTEL_PACKCOLOR(intel->intelScreen->fbFormat,
65 r,g,b,0xff));
66 }
67
68 static void intel_draw_performance_boxes( intelContextPtr intel )
69 {
70 /* Purple box for page flipping
71 */
72 if ( intel->perf_boxes & I830_BOX_FLIP )
73 intel_fill_box( intel, 4, 4, 8, 8, 255, 0, 255 );
74
75 /* Red box if we have to wait for idle at any point
76 */
77 if ( intel->perf_boxes & I830_BOX_WAIT )
78 intel_fill_box( intel, 16, 4, 8, 8, 255, 0, 0 );
79
80 /* Blue box: lost context?
81 */
82 if ( intel->perf_boxes & I830_BOX_LOST_CONTEXT )
83 intel_fill_box( intel, 28, 4, 8, 8, 0, 0, 255 );
84
85 /* Yellow box for texture swaps
86 */
87 if ( intel->perf_boxes & I830_BOX_TEXTURE_LOAD )
88 intel_fill_box( intel, 40, 4, 8, 8, 255, 255, 0 );
89
90 /* Green box if hardware never idles (as far as we can tell)
91 */
92 if ( !(intel->perf_boxes & I830_BOX_RING_EMPTY) )
93 intel_fill_box( intel, 64, 4, 8, 8, 0, 255, 0 );
94
95
96 /* Draw bars indicating number of buffers allocated
97 * (not a great measure, easily confused)
98 */
99 #if 0
100 if (intel->dma_used) {
101 int bar = intel->dma_used / 10240;
102 if (bar > 100) bar = 100;
103 if (bar < 1) bar = 1;
104 intel_fill_box( intel, 4, 16, bar, 4, 196, 128, 128 );
105 intel->dma_used = 0;
106 }
107 #endif
108
109 intel->perf_boxes = 0;
110 }
111
112
113
114
115
116
117 static int bad_prim_vertex_nr( int primitive, int nr )
118 {
119 switch (primitive & PRIM3D_MASK) {
120 case PRIM3D_POINTLIST:
121 return nr < 1;
122 case PRIM3D_LINELIST:
123 return (nr & 1) || nr == 0;
124 case PRIM3D_LINESTRIP:
125 return nr < 2;
126 case PRIM3D_TRILIST:
127 case PRIM3D_RECTLIST:
128 return nr % 3 || nr == 0;
129 case PRIM3D_POLY:
130 case PRIM3D_TRIFAN:
131 case PRIM3D_TRISTRIP:
132 case PRIM3D_TRISTRIP_RVRSE:
133 return nr < 3;
134 default:
135 return 1;
136 }
137 }
138
139 static void intel_flush_inline_primitive( GLcontext *ctx )
140 {
141 intelContextPtr intel = INTEL_CONTEXT( ctx );
142 GLuint used = intel->batch.ptr - intel->prim.start_ptr;
143 GLuint vertcount;
144
145 assert(intel->prim.primitive != ~0);
146
147 if (1) {
148 /* Check vertex size against the vertex we're specifying to
149 * hardware. If it's wrong, ditch the primitive.
150 */
151 if (!intel->vtbl.check_vertex_size( intel, intel->vertex_size ))
152 goto do_discard;
153
154 vertcount = (used - 4)/ (intel->vertex_size * 4);
155
156 if (!vertcount)
157 goto do_discard;
158
159 if (vertcount * intel->vertex_size * 4 != used - 4) {
160 fprintf(stderr, "vertex size confusion %d %d\n", used,
161 intel->vertex_size * vertcount * 4);
162 goto do_discard;
163 }
164
165 if (bad_prim_vertex_nr( intel->prim.primitive, vertcount )) {
166 fprintf(stderr, "bad_prim_vertex_nr %x %d\n", intel->prim.primitive,
167 vertcount);
168 goto do_discard;
169 }
170 }
171
172 if (used < 8)
173 goto do_discard;
174
175 *(int *)intel->prim.start_ptr = (_3DPRIMITIVE |
176 intel->prim.primitive |
177 (used/4-2));
178
179 goto finished;
180
181 do_discard:
182 intel->batch.ptr -= used;
183 intel->batch.space += used;
184 assert(intel->batch.space >= 0);
185
186 finished:
187 intel->prim.primitive = ~0;
188 intel->prim.start_ptr = 0;
189 intel->prim.flush = 0;
190 }
191
192
193 /* Emit a primitive referencing vertices in a vertex buffer.
194 */
195 void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
196 {
197 BATCH_LOCALS;
198
199 if (0)
200 fprintf(stderr, "%s %x\n", __FUNCTION__, prim);
201
202
203 /* Finish any in-progress primitive:
204 */
205 INTEL_FIREVERTICES( intel );
206
207 /* Emit outstanding state:
208 */
209 intel->vtbl.emit_state( intel );
210
211 /* Make sure there is some space in this buffer:
212 */
213 if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space) {
214 intelFlushBatch(intel, GL_TRUE);
215 intel->vtbl.emit_state( intel );
216 }
217
218 #if 1
219 if (((int)intel->batch.ptr) & 0x4) {
220 BEGIN_BATCH(1);
221 OUT_BATCH(0);
222 ADVANCE_BATCH();
223 }
224 #endif
225
226 /* Emit a slot which will be filled with the inline primitive
227 * command later.
228 */
229 BEGIN_BATCH(2);
230 OUT_BATCH( 0 );
231
232 intel->prim.start_ptr = batch_ptr;
233 intel->prim.primitive = prim;
234 intel->prim.flush = intel_flush_inline_primitive;
235 intel->batch.contains_geometry = 1;
236
237 OUT_BATCH( 0 );
238 ADVANCE_BATCH();
239 }
240
241
242 void intelRestartInlinePrimitive( intelContextPtr intel )
243 {
244 GLuint prim = intel->prim.primitive;
245
246 intel_flush_inline_primitive( &intel->ctx );
247 if (1) intelFlushBatch(intel, GL_TRUE); /* GL_TRUE - is critical */
248 intelStartInlinePrimitive( intel, prim );
249 }
250
251
252
253 void intelWrapInlinePrimitive( intelContextPtr intel )
254 {
255 GLuint prim = intel->prim.primitive;
256
257 if (0)
258 fprintf(stderr, "%s\n", __FUNCTION__);
259 intel_flush_inline_primitive( &intel->ctx );
260 intelFlushBatch(intel, GL_TRUE);
261 intelStartInlinePrimitive( intel, prim );
262 }
263
264
265 /* Emit a primitive with space for inline vertices.
266 */
267 GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
268 int primitive,
269 int dwords,
270 int vertex_size )
271 {
272 GLuint *tmp = 0;
273 BATCH_LOCALS;
274
275 if (0)
276 fprintf(stderr, "%s 0x%x %d\n", __FUNCTION__, primitive, dwords);
277
278 /* Emit outstanding state:
279 */
280 intel->vtbl.emit_state( intel );
281
282 if ((1+dwords)*4 >= intel->batch.space) {
283 intelFlushBatch(intel, GL_TRUE);
284 intel->vtbl.emit_state( intel );
285 }
286
287
288 if (1) {
289 int used = dwords * 4;
290 int vertcount;
291
292 /* Check vertex size against the vertex we're specifying to
293 * hardware. If it's wrong, ditch the primitive.
294 */
295 if (!intel->vtbl.check_vertex_size( intel, vertex_size ))
296 goto do_discard;
297
298 vertcount = dwords / vertex_size;
299
300 if (dwords % vertex_size) {
301 fprintf(stderr, "did not request a whole number of vertices\n");
302 goto do_discard;
303 }
304
305 if (bad_prim_vertex_nr( primitive, vertcount )) {
306 fprintf(stderr, "bad_prim_vertex_nr %x %d\n", primitive, vertcount);
307 goto do_discard;
308 }
309
310 if (used < 8)
311 goto do_discard;
312 }
313
314 /* Emit 3D_PRIMITIVE commands:
315 */
316 BEGIN_BATCH(1 + dwords);
317 OUT_BATCH( _3DPRIMITIVE |
318 primitive |
319 (dwords-1) );
320
321 tmp = (GLuint *)batch_ptr;
322 batch_ptr += dwords * 4;
323
324 ADVANCE_BATCH();
325
326 intel->batch.contains_geometry = 1;
327
328 do_discard:
329 return tmp;
330 }
331
332
333 static void intelWaitForFrameCompletion( intelContextPtr intel )
334 {
335 drm_i915_sarea_t *sarea = (drm_i915_sarea_t *)intel->sarea;
336
337 if (intel->do_irqs) {
338 if (intelGetLastFrame(intel) < sarea->last_dispatch) {
339 if (!intel->irqsEmitted) {
340 while (intelGetLastFrame (intel) < sarea->last_dispatch)
341 ;
342 }
343 else {
344 UNLOCK_HARDWARE( intel );
345 intelWaitIrq( intel, intel->alloc.irq_emitted );
346 LOCK_HARDWARE( intel );
347 }
348 intel->irqsEmitted = 10;
349 }
350
351 if (intel->irqsEmitted) {
352 intelEmitIrqLocked( intel );
353 intel->irqsEmitted--;
354 }
355 }
356 else {
357 while (intelGetLastFrame (intel) < sarea->last_dispatch) {
358 UNLOCK_HARDWARE( intel );
359 if (intel->do_usleeps)
360 DO_USLEEP( 1 );
361 LOCK_HARDWARE( intel );
362 }
363 }
364 }
365
366 /*
367 * Copy the back buffer to the front buffer.
368 */
369 void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
370 const drm_clip_rect_t *rect)
371 {
372 intelContextPtr intel;
373 GLboolean missed_target;
374 int64_t ust;
375
376 if (0)
377 fprintf(stderr, "%s\n", __FUNCTION__);
378
379 assert(dPriv);
380 assert(dPriv->driContextPriv);
381 assert(dPriv->driContextPriv->driverPrivate);
382
383 intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
384
385 intelFlush( &intel->ctx );
386
387 LOCK_HARDWARE( intel );
388 intelWaitForFrameCompletion( intel );
389
390 if (!rect)
391 {
392 UNLOCK_HARDWARE( intel );
393 driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
394 LOCK_HARDWARE( intel );
395 }
396 {
397 const intelScreenPrivate *intelScreen = intel->intelScreen;
398 const __DRIdrawablePrivate *dPriv = intel->driDrawable;
399 const int nbox = dPriv->numClipRects;
400 const drm_clip_rect_t *pbox = dPriv->pClipRects;
401 drm_clip_rect_t box;
402 const int cpp = intelScreen->cpp;
403 const int pitch = intelScreen->front.pitch; /* in bytes */
404 int i;
405 GLuint CMD, BR13;
406 BATCH_LOCALS;
407
408 switch(cpp) {
409 case 2:
410 BR13 = (pitch) | (0xCC << 16) | (1<<24);
411 CMD = XY_SRC_COPY_BLT_CMD;
412 break;
413 case 4:
414 BR13 = (pitch) | (0xCC << 16) | (1<<24) | (1<<25);
415 CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
416 XY_SRC_COPY_BLT_WRITE_RGB);
417 break;
418 default:
419 BR13 = (pitch) | (0xCC << 16) | (1<<24);
420 CMD = XY_SRC_COPY_BLT_CMD;
421 break;
422 }
423
424 if (0)
425 intel_draw_performance_boxes( intel );
426
427 for (i = 0 ; i < nbox; i++, pbox++)
428 {
429 if (pbox->x1 > pbox->x2 ||
430 pbox->y1 > pbox->y2 ||
431 pbox->x2 > intelScreen->width ||
432 pbox->y2 > intelScreen->height) {
433 _mesa_warning(&intel->ctx, "Bad cliprect in intelCopyBuffer()");
434 continue;
435 }
436
437 box = *pbox;
438
439 if (rect)
440 {
441 if (rect->x1 > box.x1)
442 box.x1 = rect->x1;
443 if (rect->y1 > box.y1)
444 box.y1 = rect->y1;
445 if (rect->x2 < box.x2)
446 box.x2 = rect->x2;
447 if (rect->y2 < box.y2)
448 box.y2 = rect->y2;
449
450 if (box.x1 > box.x2 || box.y1 > box.y2)
451 continue;
452 }
453
454 BEGIN_BATCH( 8);
455 OUT_BATCH( CMD );
456 OUT_BATCH( BR13 );
457 OUT_BATCH( (box.y1 << 16) | box.x1 );
458 OUT_BATCH( (box.y2 << 16) | box.x2 );
459
460 if (intel->sarea->pf_current_page == 0)
461 OUT_BATCH( intelScreen->front.offset );
462 else
463 OUT_BATCH( intelScreen->back.offset );
464
465 OUT_BATCH( (box.y1 << 16) | box.x1 );
466 OUT_BATCH( BR13 & 0xffff );
467
468 if (intel->sarea->pf_current_page == 0)
469 OUT_BATCH( intelScreen->back.offset );
470 else
471 OUT_BATCH( intelScreen->front.offset );
472
473 ADVANCE_BATCH();
474 }
475 }
476 intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE );
477 UNLOCK_HARDWARE( intel );
478
479 if (!rect)
480 {
481 intel->swap_count++;
482 (*dri_interface->getUST)(&ust);
483 if (missed_target) {
484 intel->swap_missed_count++;
485 intel->swap_missed_ust = ust - intel->swap_ust;
486 }
487
488 intel->swap_ust = ust;
489 }
490 }
491
492
493
494
495 void intelEmitFillBlitLocked( intelContextPtr intel,
496 GLuint cpp,
497 GLshort dst_pitch, /* in bytes */
498 GLuint dst_offset,
499 GLshort x, GLshort y,
500 GLshort w, GLshort h,
501 GLuint color )
502 {
503 GLuint BR13, CMD;
504 BATCH_LOCALS;
505
506 switch(cpp) {
507 case 1:
508 case 2:
509 case 3:
510 BR13 = dst_pitch | (0xF0 << 16) | (1<<24);
511 CMD = XY_COLOR_BLT_CMD;
512 break;
513 case 4:
514 BR13 = dst_pitch | (0xF0 << 16) | (1<<24) | (1<<25);
515 CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
516 XY_COLOR_BLT_WRITE_RGB);
517 break;
518 default:
519 return;
520 }
521
522 BEGIN_BATCH( 6);
523 OUT_BATCH( CMD );
524 OUT_BATCH( BR13 );
525 OUT_BATCH( (y << 16) | x );
526 OUT_BATCH( ((y+h) << 16) | (x+w) );
527 OUT_BATCH( dst_offset );
528 OUT_BATCH( color );
529 ADVANCE_BATCH();
530 }
531
532
533 /* Copy BitBlt
534 */
535 void intelEmitCopyBlitLocked( intelContextPtr intel,
536 GLuint cpp,
537 GLshort src_pitch,
538 GLuint src_offset,
539 GLshort dst_pitch,
540 GLuint dst_offset,
541 GLshort src_x, GLshort src_y,
542 GLshort dst_x, GLshort dst_y,
543 GLshort w, GLshort h )
544 {
545 GLuint CMD, BR13;
546 int dst_y2 = dst_y + h;
547 int dst_x2 = dst_x + w;
548 BATCH_LOCALS;
549
550 src_pitch *= cpp;
551 dst_pitch *= cpp;
552
553 switch(cpp) {
554 case 1:
555 case 2:
556 case 3:
557 BR13 = dst_pitch | (0xCC << 16) | (1<<24);
558 CMD = XY_SRC_COPY_BLT_CMD;
559 break;
560 case 4:
561 BR13 = dst_pitch | (0xCC << 16) | (1<<24) | (1<<25);
562 CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
563 XY_SRC_COPY_BLT_WRITE_RGB);
564 break;
565 default:
566 return;
567 }
568
569 if (dst_y2 < dst_y ||
570 dst_x2 < dst_x) {
571 return;
572 }
573
574 BEGIN_BATCH( 12);
575 OUT_BATCH( CMD );
576 OUT_BATCH( BR13 );
577 OUT_BATCH( (dst_y << 16) | dst_x );
578 OUT_BATCH( (dst_y2 << 16) | dst_x2 );
579 OUT_BATCH( dst_offset );
580 OUT_BATCH( (src_y << 16) | src_x );
581 OUT_BATCH( src_pitch );
582 OUT_BATCH( src_offset );
583 ADVANCE_BATCH();
584 }
585
586
587
588 void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
589 GLint cx1, GLint cy1, GLint cw, GLint ch)
590 {
591 intelContextPtr intel = INTEL_CONTEXT( ctx );
592 intelScreenPrivate *intelScreen = intel->intelScreen;
593 GLuint clear_depth, clear_color;
594 GLint cx, cy;
595 GLint pitch;
596 GLint cpp = intelScreen->cpp;
597 GLint i;
598 GLuint BR13, CMD, D_CMD;
599 BATCH_LOCALS;
600
601 intelFlush( &intel->ctx );
602 LOCK_HARDWARE( intel );
603
604 pitch = intelScreen->front.pitch;
605
606 clear_color = intel->ClearColor;
607 clear_depth = 0;
608
609 if (flags & BUFFER_BIT_DEPTH) {
610 clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
611 }
612
613 if (flags & BUFFER_BIT_STENCIL) {
614 clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
615 }
616
617 switch(cpp) {
618 case 2:
619 BR13 = (0xF0 << 16) | (pitch) | (1<<24);
620 D_CMD = CMD = XY_COLOR_BLT_CMD;
621 break;
622 case 4:
623 BR13 = (0xF0 << 16) | (pitch) | (1<<24) | (1<<25);
624 CMD = (XY_COLOR_BLT_CMD |
625 XY_COLOR_BLT_WRITE_ALPHA |
626 XY_COLOR_BLT_WRITE_RGB);
627 D_CMD = XY_COLOR_BLT_CMD;
628 if (flags & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB;
629 if (flags & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
630 break;
631 default:
632 BR13 = (0xF0 << 16) | (pitch) | (1<<24);
633 D_CMD = CMD = XY_COLOR_BLT_CMD;
634 break;
635 }
636
637 {
638 /* flip top to bottom */
639 cy = intel->driDrawable->h-cy1-ch;
640 cx = cx1 + intel->drawX;
641 cy += intel->drawY;
642
643 /* adjust for page flipping */
644 if ( intel->sarea->pf_current_page == 1 ) {
645 GLuint tmp = flags;
646
647 flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
648 if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT;
649 if ( tmp & BUFFER_BIT_BACK_LEFT ) flags |= BUFFER_BIT_FRONT_LEFT;
650 }
651
652 for (i = 0 ; i < intel->numClipRects ; i++)
653 {
654 drm_clip_rect_t *box = &intel->pClipRects[i];
655 drm_clip_rect_t b;
656
657 if (!all) {
658 GLint x = box->x1;
659 GLint y = box->y1;
660 GLint w = box->x2 - x;
661 GLint h = box->y2 - y;
662
663 if (x < cx) w -= cx - x, x = cx;
664 if (y < cy) h -= cy - y, y = cy;
665 if (x + w > cx + cw) w = cx + cw - x;
666 if (y + h > cy + ch) h = cy + ch - y;
667 if (w <= 0) continue;
668 if (h <= 0) continue;
669
670 b.x1 = x;
671 b.y1 = y;
672 b.x2 = x + w;
673 b.y2 = y + h;
674 } else {
675 b = *box;
676 }
677
678
679 if (b.x1 > b.x2 ||
680 b.y1 > b.y2 ||
681 b.x2 > intelScreen->width ||
682 b.y2 > intelScreen->height)
683 continue;
684
685 if ( flags & BUFFER_BIT_FRONT_LEFT ) {
686 BEGIN_BATCH( 6);
687 OUT_BATCH( CMD );
688 OUT_BATCH( BR13 );
689 OUT_BATCH( (b.y1 << 16) | b.x1 );
690 OUT_BATCH( (b.y2 << 16) | b.x2 );
691 OUT_BATCH( intelScreen->front.offset );
692 OUT_BATCH( clear_color );
693 ADVANCE_BATCH();
694 }
695
696 if ( flags & BUFFER_BIT_BACK_LEFT ) {
697 BEGIN_BATCH( 6);
698 OUT_BATCH( CMD );
699 OUT_BATCH( BR13 );
700 OUT_BATCH( (b.y1 << 16) | b.x1 );
701 OUT_BATCH( (b.y2 << 16) | b.x2 );
702 OUT_BATCH( intelScreen->back.offset );
703 OUT_BATCH( clear_color );
704 ADVANCE_BATCH();
705 }
706
707 if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
708 BEGIN_BATCH( 6);
709 OUT_BATCH( D_CMD );
710 OUT_BATCH( BR13 );
711 OUT_BATCH( (b.y1 << 16) | b.x1 );
712 OUT_BATCH( (b.y2 << 16) | b.x2 );
713 OUT_BATCH( intelScreen->depth.offset );
714 OUT_BATCH( clear_depth );
715 ADVANCE_BATCH();
716 }
717 }
718 }
719 intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
720 UNLOCK_HARDWARE( intel );
721 }
722
723
724
725
726 void intelDestroyBatchBuffer( GLcontext *ctx )
727 {
728 intelContextPtr intel = INTEL_CONTEXT(ctx);
729
730 if (intel->alloc.offset) {
731 intelFreeAGP( intel, intel->alloc.ptr );
732 intel->alloc.ptr = NULL;
733 intel->alloc.offset = 0;
734 }
735 else if (intel->alloc.ptr) {
736 free(intel->alloc.ptr);
737 intel->alloc.ptr = NULL;
738 }
739
740 memset(&intel->batch, 0, sizeof(intel->batch));
741 }
742
743
744 void intelInitBatchBuffer( GLcontext *ctx )
745 {
746 intelContextPtr intel = INTEL_CONTEXT(ctx);
747
748 /* This path isn't really safe with rotate:
749 */
750 if (getenv("INTEL_BATCH") && intel->intelScreen->allow_batchbuffer) {
751 switch (intel->intelScreen->deviceID) {
752 case PCI_CHIP_I865_G:
753 /* HW bug? Seems to crash if batchbuffer crosses 4k boundary.
754 */
755 intel->alloc.size = 8 * 1024;
756 break;
757 default:
758 /* This is the smallest amount of memory the kernel deals with.
759 * We'd ideally like to make this smaller.
760 */
761 intel->alloc.size = 1 << intel->intelScreen->logTextureGranularity;
762 break;
763 }
764
765 /* KW: temporary - this make crashes & lockups more frequent, so
766 * leave in until they are solved.
767 */
768 intel->alloc.size = 8 * 1024;
769
770 intel->alloc.ptr = intelAllocateAGP( intel, intel->alloc.size );
771 if (intel->alloc.ptr)
772 intel->alloc.offset =
773 intelAgpOffsetFromVirtual( intel, intel->alloc.ptr );
774 else
775 intel->alloc.offset = 0; /* OK? */
776 }
777
778 /* The default is now to use a local buffer and pass that to the
779 * kernel. This is also a fallback if allocation fails on the
780 * above path:
781 */
782 if (!intel->alloc.ptr) {
783 intel->alloc.size = 8 * 1024;
784 intel->alloc.ptr = malloc( intel->alloc.size );
785 intel->alloc.offset = 0;
786 }
787
788 assert(intel->alloc.ptr);
789 }